if (typeof Zapatec == 'undefined') { 
  Zapatec = function() {};
}

Zapatec.getPath = function() {
  var objContainer = document.body;
  if (!objContainer) {
    objContainer = document.getElementsByTagName('body')[0];
    if (!objContainer) {
      objContainer = document;
    }
  }
  var objScript = objContainer.lastChild;
  var strSrc = objScript.getAttribute('src');
  if (!strSrc) {
    return '';
  }
  var arrTokens = strSrc.split('/');
  arrTokens = arrTokens.slice(0, -1);
  if (!arrTokens.length) {
    return '';
  }
  return arrTokens.join('/') + '/';
};

Zapatec.include = function(strSrc) {
  document.write('<s' + 'cript type="text/javascript" src="' + strSrc +
   '"></s' + 'cript>');
};

Zapatec.zapatecPath = Zapatec.getPath();

if (Zapatec.Transport && Zapatec.Transport.include) {
  Zapatec.include = Zapatec.Transport.include;
}

if (typeof Zapatec == 'undefined') {
  Zapatec = {};
}

Zapatec.Utils = {};

Zapatec.Utils.getAbsolutePos = function(el, scrollOff) {
	var SL = 0, ST = 0;
	if (!scrollOff) {
		var is_div = /^div$/i.test(el.tagName);
		if (is_div && el.scrollLeft)
			SL = el.scrollLeft;
		if (is_div && el.scrollTop)
			ST = el.scrollTop;
	}
	var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST };
	if (el.offsetParent) {
		var tmp = this.getAbsolutePos(el.offsetParent);
		r.x += tmp.x;
		r.y += tmp.y;
	}
	return r;
};

Zapatec.Utils.fixBoxPosition = function(box) {
	if (box.x < 0)
		box.x = 0;
	if (box.y < 0)
		box.y = 0;
	var cp = Zapatec.Utils.createElement("div");
	var s = cp.style;
	s.position = "absolute";
	s.right = s.bottom = s.width = s.height = "0px";
	window.document.body.appendChild(cp);
	var br = Zapatec.Utils.getAbsolutePos(cp);
	window.document.body.removeChild(cp);
	if (Zapatec.is_ie) {
		br.y += window.document.body.scrollTop;
		br.x += window.document.body.scrollLeft;
	} else {
		br.y += window.scrollY;
		br.x += window.scrollX;
	}
	var tmp = box.x + box.width - br.x;
	if (tmp > 0) box.x -= tmp;
	tmp = box.y + box.height - br.y;
	if (tmp > 0) box.y -= tmp;
};

Zapatec.Utils.isRelated = function (el, evt) {
	evt || (evt = window.event);
	var related = evt.relatedTarget;
	if (!related) {
		var type = evt.type;
		if (type == "mouseover") {
			related = evt.fromElement;
		} else if (type == "mouseout") {
			related = evt.toElement;
		}
	}
	try {
		while (related) {
			if (related == el) {
				return true;
			}
			related = related.parentNode;
		}
	} catch(e) {};
	return false;
};

Zapatec.Utils.removeClass = function(el, className) {
	if (!(el && el.className)) {
		return;
	}
	var cls = el.className.split(" ");
	var ar = [];
	for (var i = cls.length; i > 0;) {
		if (cls[--i] != className) {
			ar[ar.length] = cls[i];
		}
	}
	el.className = ar.join(" ");
};

Zapatec.Utils.addClass = function(el, className) {
	Zapatec.Utils.removeClass(el, className);
	el.className += " " + className;
};

Zapatec.Utils.getElement = function(ev) {
	if (Zapatec.is_ie) {
		return window.event.srcElement;
	} else {
		return ev.currentTarget;
	}
};

Zapatec.Utils.getTargetElement = function(ev) {
	if (Zapatec.is_ie) {
		return window.event.srcElement;
	} else {
		return ev.target;
	}
};

Zapatec.Utils.getMousePos = function(objEvent) {
  var objPos = {
    pageX: 0,
    pageY: 0,
    clientX: 0,
    clientY: 0
  };
  var boolIsPageX = (typeof objEvent.pageX != 'undefined');
  var boolIsClientX = (typeof objEvent.clientX != 'undefined');
  objEvent || (objEvent = window.event);
  if (objEvent && (boolIsPageX || boolIsClientX)) {
    if (boolIsPageX) {
      objPos.pageX = objEvent.pageX;
      objPos.pageY = objEvent.pageY;
    } else {
      objPos.pageX = objEvent.clientX + Zapatec.Utils.getPageScrollX();
      objPos.pageY = objEvent.clientY + Zapatec.Utils.getPageScrollY();
    }
    if (boolIsClientX) {
      objPos.clientX = objEvent.clientX;
      objPos.clientY = objEvent.clientY;
    } else {
      objPos.clientX = objEvent.pageX - Zapatec.Utils.getPageScrollX();
      objPos.clientY = objEvent.pageY - Zapatec.Utils.getPageScrollY();
    }
  }
  return objPos;
};

Zapatec.Utils.stopEvent = function(ev) {
	ev || (ev = window.event);
	if (ev) {
		if (Zapatec.is_ie) {
			ev.cancelBubble = true;
			ev.returnValue = false;
		} else {
			ev.preventDefault();
			ev.stopPropagation();
		}
	}
	return false;
};

Zapatec.Utils.removeOnUnload = [];

Zapatec.Utils.addEvent = function(el, evname, func, useCapture) {
	if (el.addEventListener) {
	  if (!useCapture) {
	    useCapture = false;
	  }
		el.addEventListener(evname, func, useCapture);
	} else if (el.attachEvent) {
		el.attachEvent("on" + evname, func);
		if (useCapture) {el.setCapture(false);}
	} else {
		el["on" + evname] = func;
	}
	Zapatec.Utils.removeOnUnload.push({"element" : el, "event" : evname, "listener" : func});
};

Zapatec.Utils.removeEvent = function(el, evname, func) {
	if (el.detachEvent) {
		el.detachEvent("on" + evname, func);
	} else if (el.removeEventListener) {
		el.removeEventListener(evname, func, false);
	} else {
		el["on" + evname] = null;
	}
};

Zapatec.Utils.createElement = function(type, parent, selectable) {
	var el = null;
	if (window.self.document.createElementNS)
		el = window.self.document.createElementNS("http://www.w3.org/1999/xhtml", type);
	else
		el = window.self.document.createElement(type);
	if (typeof parent != "undefined" &&parent != null)
		parent.appendChild(el);
	if (!selectable) {
		if (Zapatec.is_ie)
			el.setAttribute("unselectable", true);
		if (Zapatec.is_gecko)
			el.style.setProperty("-moz-user-select", "none", "");
	}
	return el;
};

Zapatec.Utils.writeCookie = function(name, value, domain, path, exp_days) {
	value = escape(value);
	var ck = name + "=" + value, exp;
	if (domain)
		ck += ";domain=" + domain;
	if (path)
		ck += ";path=" + path;
	if (exp_days) {
		exp = new Date();
		exp.setTime(exp_days * 86400000 + exp.getTime());
		ck += ";expires=" + exp.toGMTString();
	}
	document.cookie = ck;
};

Zapatec.Utils.getCookie = function(name) {
	var pattern = name + "=";
	var tokenPos = 0;
	while (tokenPos < document.cookie.length) {
		var valuePos = tokenPos + pattern.length;
		if (document.cookie.substring(tokenPos, valuePos) == pattern) {
			var endValuePos = document.cookie.indexOf(";", valuePos);
			if (endValuePos == -1) {
				endValuePos = document.cookie.length;
			}
			return unescape(document.cookie.substring(valuePos, endValuePos));
		}
		tokenPos=document.cookie.indexOf(" ",tokenPos)+1;
		if (tokenPos == 0) {
			break;
		}
	}
	return null;
};

Zapatec.Utils.makePref = function(obj) {
	function stringify(val) {
		if (typeof val == "object" && !val)
			return "null";
		else if (typeof val == "number" || typeof val == "boolean")
			return val;
		else if (typeof val == "string")
			return '"' + val.replace(/\22/, "\\22") + '"';
		else return null;
	};
	var txt = "", i;
	for (i in obj)
		txt += (txt ? ",'" : "'") + i + "':" + stringify(obj[i]);
	return txt;
};

Zapatec.Utils.loadPref = function(txt) {
	var obj = null;
	try {
		eval("obj={" + txt + "}");
	} catch(e) {}
	return obj;
};

Zapatec.Utils.mergeObjects = function(dest, src) {
	for (var i in src)
		dest[i] = src[i];
};

Zapatec.Utils.__wch_id = 0;

Zapatec.Utils.createWCH = function(element) {
	var f = null;
	element = element || window.self.document.body;
	if (Zapatec.is_ie && !Zapatec.is_ie5) {
		var filter = 'filter:progid:DXImageTransform.Microsoft.alpha(style=0,opacity=0);';
		var id = "WCH" + (++Zapatec.Utils.__wch_id);
		element.insertAdjacentHTML
			('beforeEnd', '<iframe id="' + id + '" scroll="no" frameborder="0" ' +
			 'style="z-index:0;position:absolute;visibility:hidden;' + filter +
			 'border:0;top:0;left:0;width:0;height:0;" ' +
			 'src="javascript:false;"></iframe>');
		f = window.self.document.getElementById(id);
	}
	return f;
};

Zapatec.Utils.setupWCH_el = function(f, el, el2) {
	if (f) {
		var pos = Zapatec.Utils.getAbsolutePos(el),
			X1 = pos.x,
			Y1 = pos.y,
			X2 = X1 + el.offsetWidth,
			Y2 = Y1 + el.offsetHeight;
		if (el2) {
			var p2 = Zapatec.Utils.getAbsolutePos(el2),
				XX1 = p2.x,
				YY1 = p2.y,
				XX2 = XX1 + el2.offsetWidth,
				YY2 = YY1 + el2.offsetHeight;
			if (X1 > XX1)
				X1 = XX1;
			if (Y1 > YY1)
				Y1 = YY1;
			if (X2 < XX2)
				X2 = XX2;
			if (Y2 < YY2)
				Y2 = YY2;
		}
		Zapatec.Utils.setupWCH(f, X1, Y1, X2-X1, Y2-Y1);
	}
};

Zapatec.Utils.setupWCH = function(f, x, y, w, h) {
	if (f) {
		var s = f.style;
		(typeof x != "undefined") && (s.left = x + "px");
		(typeof y != "undefined") && (s.top = y + "px");
		(typeof w != "undefined") && (s.width = w + "px");
		(typeof h != "undefined") && (s.height = h + "px");
		s.visibility = "inherit";
	}
};

Zapatec.Utils.hideWCH = function(f) {
	if (f)
		f.style.visibility = "hidden";
};

Zapatec.Utils.getPageScrollY = function() {
	return window.pageYOffset ||
			document.documentElement.scrollTop ||
			(document.body ? document.body.scrollTop : 0) ||
			0;
};

Zapatec.Utils.getPageScrollX = function() {
	return window.pageXOffset ||
			document.documentElement.scrollLeft ||
			(document.body ? document.body.scrollLeft : 0) ||
			0;
};

Zapatec.ScrollWithWindow = {};
Zapatec.ScrollWithWindow.list = [];
Zapatec.ScrollWithWindow.stickiness = 0.25;

Zapatec.ScrollWithWindow.register = function(node) {
	var top = node.offsetTop || 0;
	var left = node.offsetLeft || 0;
	node.parentNode.style.position = "relative";
	var scrollY = Zapatec.Utils.getPageScrollY();
	var scrollX = Zapatec.Utils.getPageScrollX();
	top -= scrollY;
	left -= scrollX;
	Zapatec.ScrollWithWindow.list[Zapatec.ScrollWithWindow.list.length] = {
		node: node,
		origTop: top,
		origleft: left
	};
};

Zapatec.ScrollWithWindow.unregister = function(node) {
	for (var count = 0; count < Zapatec.ScrollWithWindow.list.length; count++) {
		var elm = Zapatec.ScrollWithWindow.list[count];
		if (node == elm.node) {
			Zapatec.ScrollWithWindow.list.splice(count, 1);
			return;
		}
	}
};

Zapatec.ScrollWithWindow.handler = function(newScroll, direction) {
	if (direction == "vertical") {
		var newScrollY = newScroll;
		oldScrollY += ((newScrollY - oldScrollY) * this.stickiness);
		if (Math.abs(oldScrollY - newScrollY) <= 1) oldScrollY = newScrollY;
	} else {
		var newScrollX = newScroll;
		oldScrollX += ((newScrollX - oldScrollX) * this.stickiness);
		if (Math.abs(oldScrollX - newScrollX) <= 1) oldScrollX = newScrollX;
	}
	for (var count = 0; count < Zapatec.ScrollWithWindow.list.length; count++) {
		var elm = Zapatec.ScrollWithWindow.list[count];
		var node = elm.node;
		node.style.position = 'absolute';
		if (!elm.origTop && elm.origTop !== 0 && (direction == "vertical")) {
			elm.origTop = parseInt(node.style.top) || 0;
		}
		if (!elm.origLeft && elm.origLeft !== 0 && (direction == "horizontal")) {
			elm.origLeft = parseInt(node.style.left) || 0;
		}
		if (direction == "vertical") {
			node.style.top = (elm.origTop + parseInt(oldScrollY)) + 'px';
		} else {
			node.style.left = (elm.origLeft + parseInt(oldScrollX)) + 'px';
		}
	}
};

var oldScrollY = Zapatec.Utils.getPageScrollY();
var oldScrollX = Zapatec.Utils.getPageScrollX();
setInterval(
	'var newScrollY = Zapatec.Utils.getPageScrollY(); ' +
	'var newScrollX = Zapatec.Utils.getPageScrollX(); ' +
	'if (newScrollY != oldScrollY) { ' +
		'Zapatec.ScrollWithWindow.handler(newScrollY, "vertical"); ' +
	'}' +
	'if (newScrollX != oldScrollX) { ' +
		'Zapatec.ScrollWithWindow.handler(newScrollX, "horizontal"); ' +
	'}', 50);

Zapatec.Utils.destroy = function(el) {
	if (el && el.parentNode)
		el.parentNode.removeChild(el);
};

Zapatec.Utils.newCenteredWindow = function(url, windowName, width, height, scrollbars){
	var leftPosition = 0;
	var topPosition = 0;
	if (screen.width)
		leftPosition = (screen.width -  width)/2;
	if (screen.height)
		topPosition = (screen.height -  height)/2;
	var winArgs =
		'height=' + height +
		',width=' + width +
		',top=' + topPosition +
		',left=' + leftPosition +
		',scrollbars=' + scrollbars +
		',resizable';
	var win = window.open(url,windowName,winArgs);
	return win;
};

Zapatec.Utils.getWindowSize = function() {
	var iWidth = 0;
	var iHeight = 0;
	if (document.compatMode && document.compatMode == 'CSS1Compat') {
		if (window.opera) {
			iWidth = document.body.clientWidth || 0;
			iHeight = document.body.clientHeight || 0;
		} else {
			iWidth = document.documentElement.clientWidth || 0;
			iHeight = document.documentElement.clientHeight || 0;
		}
	} else {
		iWidth = window.innerWidth || document.body.clientWidth ||
			document.documentElement.clientWidth || 0;
		iHeight = window.innerHeight || document.body.clientHeight ||
			document.documentElement.clientHeight || 0;
	}
	return {
		width: iWidth,
		height: iHeight
	};
};

Zapatec.Utils.selectOption = function(sel, val, call_default) {
	var a = sel.options, i, o;
	for (i = a.length; --i >= 0;) {
		o = a[i];
		o.selected = (o.val == val);
	}
	sel.value = val;
	if (call_default) {
		if (typeof sel.onchange == "function")
			sel.onchange();
		else if (typeof sel.onchange == "string")
			eval(sel.onchange);
	}
};

Zapatec.Utils.getNextSibling = function(el, tag, alternateTag) {
	el = el.nextSibling;
	if (!tag) {
		return el;
	}
	tag = tag.toLowerCase();
	if (alternateTag) alternateTag = alternateTag.toLowerCase();
	while (el) {
		if (el.nodeType == 1 && (el.tagName.toLowerCase() == tag ||
		 (alternateTag && el.tagName.toLowerCase() == alternateTag))) {
			return el;
		}
		el = el.nextSibling;
	}
	return el;
};

Zapatec.Utils.getFirstChild = function(el, tag, alternateTag) {
  if (!el) {
    return null;
  }
	el = el.firstChild;
  if (!el) {
    return null;
  }
	if (!tag) {
		return el;
	}
	tag = tag.toLowerCase();
	if (el.nodeType == 1) {
		if (el.tagName.toLowerCase() == tag) {
			return el;
		} else if (alternateTag) {
			alternateTag = alternateTag.toLowerCase();
			if (el.tagName.toLowerCase() == alternateTag) {
				return el;
			}
		}
	}
	return Zapatec.Utils.getNextSibling(el, tag, alternateTag);
};

Zapatec.Utils.getChildText = function(objNode) {
	if (objNode == null) {
		return '';
	}
	var arrText = [];
	var objChild = objNode.firstChild;
	while (objChild != null) {
		if (objChild.nodeType == 3) {
			arrText.push(objChild.data);
		}
		objChild = objChild.nextSibling;
	}
	return arrText.join(' ');
};

Zapatec.Utils.insertAfter = function(oldNode, newNode) {
	if(oldNode.nextSibling) {
		oldNode.parentNode.insertBefore(newNode, oldNode.nextSibling);
	} else {
		oldNode.parentNode.appendChild(newNode);
	}
}

Zapatec.Utils._ids = {};

Zapatec.Utils.generateID = function(code, id) {
	if (typeof id == "undefined") {
		if (typeof this._ids[code] == "undefined")
			this._ids[code] = 0;
		id = ++this._ids[code];
	}
	return "zapatec-" + code + "-" + id;
};

Zapatec.Utils.addTooltip = function(target, tooltip) {
  return new Zapatec.Tooltip(target, tooltip);
};

Zapatec.isLite=true;

Zapatec.Utils.checkActivation = function() {
	if (!Zapatec.isLite)	return true;
	var arrProducts=[]
	add_product=function(script, webdir_in, name_in)
	{
	arrProducts[script]={webdir:webdir_in, name:name_in, bActive:false}
	}
	var strName, arrName, i
	var bProduct=false
	var scripts = document.getElementsByTagName('script');
	for (i=0; i<scripts.length; i++)
	{
		if (/wizard.js/i.test(scripts[i].src))
			return true
		arrName=scripts[i].src.split('/')
		if (arrName.length==0)
			strName=scripts[i]
		else
			strName=arrName[arrName.length-1]
		strName=strName.toLowerCase()
		if (typeof arrProducts[strName] != 'undefined')
			{
			bProduct=true
			arrProducts[strName].bActive=true
			}
	}
	if (!bProduct) return true;
	var anchors = document.getElementsByTagName('A');
	for(i = 0; i < anchors.length; i++)
		if (/(dev|www)\.zapatec\.com/i.test(anchors[i].href))
			return true;
	var strMsg=''
	for (i in arrProducts)
		if (arrProducts[i].bActive==true)
			strMsg+=''
	return false;
}

Zapatec.is_opera = /opera/i.test(navigator.userAgent);
Zapatec.is_ie = ( /msie/i.test(navigator.userAgent) && !Zapatec.is_opera );
Zapatec.is_ie5 = ( Zapatec.is_ie && /msie 5\.0/i.test(navigator.userAgent) );
Zapatec.is_mac_ie = ( /msie.*mac/i.test(navigator.userAgent) && !Zapatec.is_opera );
Zapatec.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent);
Zapatec.is_konqueror = /Konqueror/i.test(navigator.userAgent);
Zapatec.is_gecko = /Gecko/i.test(navigator.userAgent);

if (!Object.prototype.hasOwnProperty) {
  Object.prototype.hasOwnProperty = function(strProperty) {
    try {
      var objPrototype = this.constructor.prototype;
      while (objPrototype) {
        if (objPrototype[strProperty] == this[strProperty]) {
          return false;
        }
        objPrototype = objPrototype.prototype;
      }
    } catch (objException) {}
    return true;
  };
}

if (!Function.prototype.call) {
	Function.prototype.call = function() {
		var objThis = arguments[0];
		objThis._this_func = this;
		var arrArgs = [];
		for (var iArg = 1; iArg < arguments.length; iArg++) {
			arrArgs[arrArgs.length] = 'arguments[' + iArg + ']';
		}
		var ret = eval('objThis._this_func(' + arrArgs.join(',') + ')');
		objThis._this_func = null;
		return ret;
	};
}

if (!Function.prototype.apply) {
	Function.prototype.apply = function() {
		var objThis = arguments[0];
		var objArgs = arguments[1];
		objThis._this_func = this;
		var arrArgs = [];
		if (objArgs) {
			for (var iArg = 0; iArg < objArgs.length; iArg++) {
				arrArgs[arrArgs.length] = 'objArgs[' + iArg + ']';
			}
		}
		var ret = eval('objThis._this_func(' + arrArgs.join(',') + ')');
		objThis._this_func = null;
		return ret;
	};
}

if (!Array.prototype.pop) {
	Array.prototype.pop = function() {
		var last;
		if (this.length) {
			last = this[this.length - 1];
			this.length -= 1;
		}
		return last;
	};
}

if (!Array.prototype.push) {
	Array.prototype.push = function() {
		for (var i = 0; i < arguments.length; i++) {
			this[this.length] = arguments[i];
		}
		return this.length;
	};
}

if (!Array.prototype.shift) {
	Array.prototype.shift = function() {
		var first;
		if (this.length) {
			first = this[0];
			for (var i = 0; i < this.length - 1; i++) {
				this[i] = this[i + 1];
			}
			this.length -= 1;
		}
		return first;
	};
}

if (!Array.prototype.unshift) {
	Array.prototype.unshift = function() {
		if (arguments.length) {
			var i, len = arguments.length;
			for (i = this.length + len - 1; i >= len; i--) {
				this[i] = this[i - len];
			}
			for (i = 0; i < len; i++) {
				this[i] = arguments[i];
			}
		}
		return this.length;
	};
}

if (!Array.prototype.splice) {
	Array.prototype.splice = function(index, howMany) {
		var elements = [], removed = [], i;
		for (i = 2; i < arguments.length; i++) {
			elements.push(arguments[i]);
		}
		for (i = index; (i < index + howMany) && (i < this.length); i++) {
			removed.push(this[i]);
		}
		for (i = index + howMany; i < this.length; i++) {
			this[i - howMany] = this[i];
		}
		this.length -= removed.length;
		for (i = this.length + elements.length - 1; i >= index + elements.length;
		 i--) {
			this[i] = this[i - elements.length];
		}
		for (i = 0; i < elements.length; i++) {
			this[index + i] = elements[i];
		}
		return removed;
	};
}

Zapatec.Utils.arrIndexOf = function(arr, searchElement, fromIndex) {
  if (Array.prototype.indexOf) {
    return arr.indexOf(searchElement, fromIndex);
  }
  if (!fromIndex) {
    fromIndex = 0;
  }
  for (var iElement = fromIndex; iElement < arr.length; iElement++) {
    if (arr[iElement] == searchElement) {
      return iElement;
    }
  }
  return -1;
};

Zapatec.Log = function(objArgs) {
  if (!objArgs) {
    return;
  }
  var strMessage = objArgs.description;
  if (objArgs.severity) {
    strMessage = objArgs.severity + ':\n' + strMessage;
  }
  alert(strMessage);
};

Zapatec.Utils.Array = {};

Zapatec.Utils.Array.insertBefore = function (arr, el, key, nextKey) {
	var tmp = new Array();
	for(var i in arr) {
		if (i == nextKey) {
			if (key) {
				tmp[key] = el;
			} else {
				tmp.push(el);
			}
		}
		tmp[i] = arr[i];
	}
	return tmp;
}

Zapatec.inherit = function(objSubClass, objSuperClass) {
  var Inheritance = function() {};
  Inheritance.prototype = objSuperClass.prototype;
  objSubClass.prototype = new Inheritance();
  objSubClass.prototype.constructor = objSubClass;
  objSubClass.SUPERconstructor = objSuperClass;
  objSubClass.SUPERclass = objSuperClass.prototype;
  if (typeof objSuperClass.path != 'undefined') {
    objSubClass.path = Zapatec.getPath();
  }
};

Zapatec.getPath = function() {
  if(Zapatec.lastLoadedModule != null){
    return Zapatec.lastLoadedModule;	
  }
  var objContainer = document.body;
  if (!objContainer) {
    objContainer = document.getElementsByTagName('body')[0];
    if (!objContainer) {
      objContainer = document;
    }
  }
  var objScript = objContainer.lastChild;
  if(
    objScript.nodeType != 1 ||
    objScript.nodeName.toLowerCase() != 'script'
  ){
  	return "";
  }
  var strSrc = objScript.getAttribute('src');
  if (!strSrc) {
    return '';
  }
  var arrTokens = strSrc.split('/');
  arrTokens = arrTokens.slice(0, -1);
  if (!arrTokens.length) {
    return '';
  }
  return arrTokens.join('/') + '/';
};

Zapatec.windowLoaded = typeof(document.readyState) != 'undefined' ?
	(
		document.readyState == 'loaded' ||
		document.readyState == 'complete'
	) :
	document.getElementsByTagName != null && typeof(document.getElementsByTagName('body')[0]) != 'undefined'
;

Zapatec.Utils.addEvent(window, "load", function() {Zapatec.windowLoaded = true;});

Zapatec.Utils.warnUnload = function(msg, win){
    Zapatec.Utils.warnUnloadFlag = true;
	if(typeof(msg) != "string"){
		msg = "All your changes will be lost.";
	}
	if(typeof(win) == 'undefined'){
		win = window;
	}
	Zapatec.Utils.addEvent(win, 'beforeunload', function(ev){
		if(Zapatec.Utils.warnUnloadFlag != true){
			return true;
		}
		if(typeof(ev) == 'undefined'){
			ev = window.event;
	    }
		ev.returnValue = msg;
		return false;
	});
}

Zapatec.Utils.unwarnUnload = function(msg, win){
    Zapatec.Utils.warnUnloadFlag = false;
}

Zapatec.Utils.warnUnloadFlag = false;

Zapatec.Utils.getMaxZindex = function() {
  if (window.opera || Zapatec.is_khtml) {
    return 2147483583;
  } else if (Zapatec.is_ie){
    return 2147483647;
  } else {
    return 10737418239;
  }
};

Zapatec.Utils.correctCssLength = function(val) {
  if (typeof val == 'undefined' || (typeof val == 'object' && !val)) {
    return 'auto';
  }
  val += '';
  if (!val.length) {
    return 'auto';
  }
  if (/\d$/.test(val)) {
    val += 'px';
  }
  return val;
};

Zapatec.Utils.destroyOnUnload = [];

Zapatec.Utils.addDestroyOnUnload = function(objElement, strProperty) {
  Zapatec.Utils.destroyOnUnload.push([objElement, strProperty]);
};

Zapatec.Utils.createProperty = function(objElement, strProperty, val) {
  objElement[strProperty] = val;
  Zapatec.Utils.addDestroyOnUnload(objElement, strProperty);
};

Zapatec.Utils.addEvent(window, 'unload', function() {
  for (var iObj = Zapatec.Utils.destroyOnUnload.length - 1; iObj >= 0; iObj--) {
    var objDestroy = Zapatec.Utils.destroyOnUnload[iObj];
    objDestroy[0][objDestroy[1]] = null;
    objDestroy[0] = null;
  }
  for (var iLis = Zapatec.Utils.removeOnUnload.length - 1; iLis >= 0; iLis--) {
  	var listener = Zapatec.Utils.removeOnUnload[iLis];
	Zapatec.Utils.removeEvent(listener["element"], listener["event"], listener["listener"]);
  }
});

if (typeof Zapatec == 'undefined') {
  Zapatec = function() {};
}

Zapatec.Transport = function() {};

if (typeof ActiveXObject != 'undefined') {
  Zapatec.Transport.XMLDOM = null;
  Zapatec.Transport.XMLHTTP = null;
  Zapatec.Transport.pickActiveXVersion = function(arrVersions) {
    for (var iVn = 0; iVn < arrVersions.length; iVn++) {
      try {
        var objDocument = new ActiveXObject(arrVersions[iVn]);
        return arrVersions[iVn];
      } catch (objException) {};
    }
    return null;
  };
  Zapatec.Transport.XMLDOM = Zapatec.Transport.pickActiveXVersion([
    'Msxml2.DOMDocument.4.0',
    'Msxml2.DOMDocument.3.0',
    'MSXML2.DOMDocument',
    'MSXML.DOMDocument',
    'Microsoft.XMLDOM'
  ]);
  Zapatec.Transport.XMLHTTP = Zapatec.Transport.pickActiveXVersion([
    'Msxml2.XMLHTTP.4.0',
    'MSXML2.XMLHTTP.3.0',
    'MSXML2.XMLHTTP',
    'Microsoft.XMLHTTP'
  ]);
  Zapatec.Transport.pickActiveXVersion = null;
}

Zapatec.Transport.createXmlHttpRequest = function() {
  if (typeof XMLHttpRequest != 'undefined') {
    return new XMLHttpRequest();
  }
  if (typeof ActiveXObject != 'undefined') {
    try {
      return new ActiveXObject(Zapatec.Transport.XMLHTTP);
    } catch (objException) {};
  }
  return null;
};

Zapatec.Transport.isBusy = function(objArgs) {
  var objContainer = objArgs.busyContainer;
  if (typeof objContainer == 'string') {
    objContainer = document.getElementById(objContainer);
  }
  if (!objContainer) {
    return;
  }
  var strImage = objArgs.busyImage;
  if (typeof strImage != 'string') {
    strImage = '';
  }
  strImage = strImage.split('/').pop();
  if (!strImage.length) {
    strImage = 'zpbusy.gif';
  }
  var objFC = objContainer.firstChild;
  if (objFC) {
    objFC = objFC.firstChild;
    if (objFC) {
      objFC = objFC.firstChild;
      if (objFC && objFC.tagName && objFC.tagName == 'img') {
        var strSrc = objFC.getAttribute('src');
        if (typeof strSrc == 'string' && strSrc.length) {
          strSrc = strSrc.split('/').pop();
          if (strSrc == strImage) {
            return true;
          }
        }
      }
    }
  }
  return false;
};

Zapatec.Transport.showBusy = function(objArgs) {
  if (Zapatec.Transport.isBusy(objArgs)) {
    return;
  }
  var objContainer = objArgs.busyContainer;
  if (typeof objContainer == 'string') {
    objContainer = document.getElementById(objContainer);
  }
  if (!objContainer) {
    return;
  }
  var strImage = objArgs.busyImage;
  var strImageWidth = objArgs.busyImageWidth;
  var strImageHeight = objArgs.busyImageHeight;
  if (typeof strImage != 'string' || !strImage.length) {
    strImage = '';
  } else {
    if (typeof strImageWidth == 'number' ||
     (typeof strImageWidth == 'string' && /\d$/.test(strImageWidth))) {
      strImageWidth += 'px';
    }
    if (typeof strImageHeight == 'number' ||
     (typeof strImageHeight == 'string' && /\d$/.test(strImageHeight))) {
      strImageHeight += 'px';
    }
  }
  if (!strImageWidth) {
    strImageWidth = '65px';
  }
  if (!strImageHeight) {
    strImageHeight = '35px';
  }
  var strPath = '';
  if (strImage.indexOf('/') < 0) {
    strPath = Zapatec.Transport.getPath('transport.js');
  }
  var arrImgTag = [];
  arrImgTag.push('<img src="');
  arrImgTag.push(strPath);
  arrImgTag.push(strImage);
  arrImgTag.push('"');
  if (strImageWidth || strImageHeight) {
    arrImgTag.push(' style="');
    if (strImageWidth) {
      arrImgTag.push('width:');
      arrImgTag.push(strImageWidth);
      arrImgTag.push(';');
    }
    if (strImageHeight) {
      arrImgTag.push('height:');
      arrImgTag.push(strImageHeight);
    }
    arrImgTag.push('"');
  }
  arrImgTag.push(' />');
  strImgTag = arrImgTag.join('');
  var iContainerWidth = objContainer.offsetWidth;
  var iContainerHeight = objContainer.offsetHeight;
  var objBusyContainer = Zapatec.Utils.createElement('div');
  objBusyContainer.style.position = 'relative';
  objBusyContainer.style.zIndex = 2147483583;
  var objBusy = Zapatec.Utils.createElement('div', objBusyContainer);
  objBusy.style.position = 'absolute';
  objBusy.innerHTML = strImgTag;
  if (objContainer.firstChild) {
    objContainer.insertBefore(objBusyContainer, objContainer.firstChild);
  } else {
    objContainer.appendChild(objBusyContainer);
  }
  var iBusyWidth = objBusy.offsetWidth;
  var iBusyHeight = objBusy.offsetHeight;
  if (iContainerWidth > iBusyWidth) {
    objBusy.style.left = objContainer.scrollLeft +
     (iContainerWidth - iBusyWidth) / 2 + 'px';
  }
  if (iContainerHeight > iBusyHeight) {
    objBusy.style.top = objContainer.scrollTop +
     (iContainerHeight - iBusyHeight) / 2 + 'px';
  }
};

Zapatec.Transport.removeBusy = function(objArgs) {
  var objContainer = objArgs.busyContainer;
  if (typeof objContainer == 'string') {
    objContainer = document.getElementById(objContainer);
  }
  if (!objContainer) {
    return;
  }
  if (Zapatec.Transport.isBusy(objArgs)) {
    objContainer.removeChild(objContainer.firstChild);
  }
};

Zapatec.Transport.fetch = function(objArgs) {
  if (objArgs == null || typeof objArgs != 'object') {
    return null;
  }
  if (!objArgs.url) {
    return null;
  }
  if (!objArgs.method) {
    objArgs.method = 'GET';
  }
  if (typeof objArgs.async == 'undefined') {
    objArgs.async = true;
  }
  if (!objArgs.contentType && objArgs.method.toUpperCase() == 'POST') {
    objArgs.contentType = 'application/x-www-form-urlencoded';
  }
  if (!objArgs.content) {
    objArgs.content = null;
  }
  if (!objArgs.onLoad) {
    objArgs.onLoad = null;
  }
  if (!objArgs.onError) {
    objArgs.onError = null;
  }
  var objRequest = Zapatec.Transport.createXmlHttpRequest();
  if (objRequest == null) {
    return null;
  }
  Zapatec.Transport.showBusy(objArgs);
  var boolErrorDisplayed = false;
  try {
    if (typeof objArgs.username != 'undefined' &&
     typeof objArgs.password != 'undefined') {
      objRequest.open(objArgs.method, objArgs.url, objArgs.async,
       objArgs.username, objArgs.password);
    } else {
      objRequest.open(objArgs.method, objArgs.url, objArgs.async);
    }
    var funcOnReady = function () {
      Zapatec.Transport.removeBusy(objArgs);
      if (objRequest.status == 200 || objRequest.status == 304 ||
       (location.protocol == 'file:' && !objRequest.status)) {
        if (typeof objArgs.onLoad == 'function') {
          objArgs.onLoad(objRequest);
        }
      } else if (!boolErrorDisplayed) {
        boolErrorDisplayed = true;
        Zapatec.Transport.displayError(objRequest.status,
         'Error: Cannot fetch ' + objArgs.url + '.\n' +
         (objRequest.statusText || ''),
         objArgs.onError);
      }
    };
    if (objArgs.async) {
      objRequest.onreadystatechange = function () {
        if (objRequest.readyState == 4) {
          funcOnReady();
 	  objRequest.onreadystatechange = {}; 
 	}
      };
    }
    if (objArgs.contentType) {
      objRequest.setRequestHeader('Content-Type', objArgs.contentType);
    }
    objRequest.send(objArgs.content);
    if (!objArgs.async) {
      funcOnReady();
      return objRequest;
    }
  } catch (objException) {
    Zapatec.Transport.removeBusy(objArgs);
    if (!boolErrorDisplayed) {
      boolErrorDisplayed = true;
      if (objException.name &&
       objException.name == 'NS_ERROR_FILE_NOT_FOUND') {
        Zapatec.Transport.displayError(0,
         'Error: Cannot fetch ' + objArgs.url + '.\nFile not found.',
         objArgs.onError);
      } else {
        Zapatec.Transport.displayError(0,
         'Error: Cannot fetch ' + objArgs.url + '.\n' +
         (objException.message || ''),
         objArgs.onError);
      }
    }
  };
  return null;
};

Zapatec.Transport.parseHtml = function(strHtml) {
  strHtml += '';
  strHtml = strHtml.replace(/^\s+/g, '');
  var objTempContainer = null;
	if (document.createElementNS) {
		objTempContainer =
		 document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
	} else {
		objTempContainer = document.createElement('div');
	}
  objTempContainer.innerHTML = strHtml;
  return objTempContainer;
};

Zapatec.Transport.evalGlobalScope = function(strScript) {
  if (typeof strScript != 'string' || !strScript.match(/\S/)) {
    return;
  }
  if (window.execScript) {
    window.execScript(strScript, 'javascript');
  } else if (window.eval) {
    window.eval(strScript);
  }
};

Zapatec.Transport.setInnerHtml = function(objArgs) {
  if (!objArgs || typeof objArgs.html != 'string') {
    return;
  }
  var strHtml = objArgs.html;
  var objContainer = null;
  if (typeof objArgs.container == 'string') {
    objContainer = document.getElementById(objArgs.container);
  } else if (typeof objArgs.container == 'object') {
    objContainer = objArgs.container;
  }
  var arrScripts = [];
  if (strHtml.match(/<\s*\/\s*script\s*>/i)) {
    var arrTokens = strHtml.split(/<\s*\/\s*script\s*>/i);
    var arrHtml = [];
    for (var iToken = arrTokens.length - 1; iToken >= 0; iToken--) {
      var strToken = arrTokens[iToken];
      if (strToken.match(/\S/)) {
        var arrMatch = strToken.match(/<\s*script([^>]*)>/i);
        if (arrMatch) {
          var arrCouple = strToken.split(/<\s*script[^>]*>/i);
          while (arrCouple.length < 2) {
            if (strToken.match(/^<\s*script[^>]*>/i)) {
              arrCouple.unshift('');
            } else {
              arrCouple.push('');
            }
          }
          arrHtml.unshift(arrCouple[0]);
          var strAttrs = arrMatch[1];
          var srtScript = arrCouple[1];
          if (strAttrs.match(/\s+src\s*=/i)) {
            srtScript = '';
          } else {
            srtScript = srtScript.replace(/function\s+([^(]+)/g, '$1=function');
          }
          arrScripts.push([strAttrs, srtScript]);
        } else if (iToken < arrTokens.length - 1) {
          arrTokens[iToken - 1] += '</script>' + strToken;
        } else {
          arrHtml.unshift(strToken);
        }
      } else {
        arrHtml.unshift(strToken);
      }
    }
    strHtml = arrHtml.join('');
  }
  if (objContainer) {
    objContainer.innerHTML = '<form></form>';
    objContainer.innerHTML = strHtml;
  }
  for (var iScript = 0; iScript < arrScripts.length; iScript++) {
    if (arrScripts[iScript][1].length) {
      Zapatec.Transport.evalGlobalScope(arrScripts[iScript][1]);
    }
    var strAttrs = arrScripts[iScript][0];
    strAttrs = strAttrs.replace(/\s+/g, ' ').replace(/^\s/, '')
     .replace(/\s$/, '').replace(/ = /g, '=');
    if (strAttrs.indexOf('src=') >= 0) {
      var objContainer = document.body;
      if (!objContainer) {
        objContainer = document.getElementsByTagName('body')[0];
        if (!objContainer) {
          objContainer = document;
        }
      }
      var arrAttrs = strAttrs.split(' ');
      var objScript = Zapatec.Utils.createElement('script');
      for (var iAttr = 0; iAttr < arrAttrs.length; iAttr++) {
        var arrAttr = arrAttrs[iAttr].split('=');
        if (arrAttr.length > 1) {
          objScript.setAttribute(arrAttr[0],
           arrAttr[1].match(/^[\s|"|']*([\s|\S]*[^'|"])[\s|"|']*$/)[1]);
        } else {
          objScript.setAttribute(arrAttr[0], arrAttr[0]);
        }
      }
      objContainer.appendChild(objScript);
    }
  }
};

Zapatec.Transport.fetchXmlDoc = function(objArgs) {
  if (objArgs == null || typeof objArgs != 'object') {
    return null;
  }
  if (!objArgs.url) {
    return null;
  }
  if (typeof objArgs.async == 'undefined') {
    objArgs.async = true;
  }
  if (!objArgs.onLoad) {
    objArgs.onLoad = null;
  }
  if (!objArgs.onError) {
    objArgs.onError = null;
  }
  if (!objArgs.method && typeof objArgs.username == 'undefined' &&
   typeof objArgs.password == 'undefined') {
    if (document.implementation && document.implementation.createDocument) {
      var objDocument = document.implementation.createDocument('', '', null);
      if (objDocument.load) {
        objDocument.async = objArgs.async;
        if (objArgs.async) {
          objDocument.onload = function() {
            Zapatec.Transport.removeBusy(objArgs);
            Zapatec.Transport.onXmlDocLoad(objDocument, objArgs.onLoad,
             objArgs.onError);
          };
        }
        Zapatec.Transport.showBusy(objArgs);
        try {
          objDocument.load(objArgs.url);
          if (!objArgs.async) {
            Zapatec.Transport.removeBusy(objArgs);
            Zapatec.Transport.onXmlDocLoad(objDocument, objArgs.onLoad,
             objArgs.onError);
            return objDocument;
          }
          return null;
        } catch (objException) {
          Zapatec.Transport.removeBusy(objArgs);
          if (objException.name &&
           objException.name == 'NS_ERROR_FILE_NOT_FOUND') {
            Zapatec.Transport.displayError(0,
             'Error: Cannot fetch ' + objArgs.url + '.\nFile not found.',
             objArgs.onError);
          } else {
            Zapatec.Transport.displayError(0,
             'Error: Cannot fetch ' + objArgs.url + '.\n' +
             objException.toString(),
             objArgs.onError);
          }
        };
      }
    }
    if (typeof ActiveXObject != 'undefined') {
      Zapatec.Transport.showBusy(objArgs);
      try {
        var objDocument = new ActiveXObject(Zapatec.Transport.XMLDOM);
        objDocument.async = objArgs.async;
        if (objArgs.async) {
          objDocument.onreadystatechange = function () {
            if (objDocument.readyState == 4) {
              Zapatec.Transport.removeBusy(objArgs);
              Zapatec.Transport.onXmlDocLoad(objDocument, objArgs.onLoad,
               objArgs.onError);
              objDocument.onreadystatechange = {}; 
            }
          };
        }
        objDocument.load(objArgs.url);
        if (!objArgs.async) {
          Zapatec.Transport.removeBusy(objArgs);
          Zapatec.Transport.onXmlDocLoad(objDocument, objArgs.onLoad,
           objArgs.onError);
          return objDocument;
        }
        return null;
      } catch (objException) {
        Zapatec.Transport.removeBusy(objArgs);
      };
    }
  }
  var objFetchArgs = {};
  for (var strKey in objArgs) {
    objFetchArgs[strKey] = objArgs[strKey];
  }
  if (objArgs.async) {
    objFetchArgs.onLoad = function(objRequest) {
      Zapatec.Transport.parseXml({
        strXml: objRequest.responseText,
        onLoad: objArgs.onLoad,
        onError: objArgs.onError
      });
    };
  } else {
    objFetchArgs.onLoad = null;
  }
  var objRequest = Zapatec.Transport.fetch(objFetchArgs);
  if (!objArgs.async && objRequest) {
    return Zapatec.Transport.parseXml({
      strXml: objRequest.responseText,
      onLoad: objArgs.onLoad,
      onError: objArgs.onError
    });
  }
  return null;
};

Zapatec.Transport.parseXml = function(objArgs) {
  if (objArgs == null || typeof objArgs != 'object') {
    return null;
  }
  if (!objArgs.strXml) {
    return null;
  }
  if (!objArgs.onLoad) {
    objArgs.onLoad = null;
  }
  if (!objArgs.onError) {
    objArgs.onError = null;
  }
  if (window.DOMParser) {
    try {
      var objDocument = (new DOMParser()).parseFromString(objArgs.strXml,
       'text/xml');
      Zapatec.Transport.onXmlDocLoad(objDocument, objArgs.onLoad,
       objArgs.onError);
      return objDocument;
    } catch (objException) {
      Zapatec.Transport.displayError(0,
       'Error: Cannot parse.\n' +
       'String does not appear to be a valid XML fragment.',
       objArgs.onError);
    };
    return null;
  }
  if (typeof ActiveXObject != 'undefined') {
    try {
      var objDocument = new ActiveXObject(Zapatec.Transport.XMLDOM);
      objDocument.loadXML(objArgs.strXml);
      Zapatec.Transport.onXmlDocLoad(objDocument, objArgs.onLoad,
       objArgs.onError);
      return objDocument;
    } catch (objException) {};
  }
  return null;
};

Zapatec.Transport.onXmlDocLoad = function(objDocument, onLoad, onError) {
  var strError = null;
  if (objDocument.parseError) {
    strError = objDocument.parseError.reason;
    if (objDocument.parseError.srcText) {
      strError += 'Location: ' + objDocument.parseError.url +
       '\nLine number ' + objDocument.parseError.line + ', column ' +
       objDocument.parseError.linepos + ':\n' +
       objDocument.parseError.srcText + '\n';
    }
  } else if (objDocument.documentElement &&
   objDocument.documentElement.tagName == 'parsererror') {
    strError = objDocument.documentElement.firstChild.data + '\n' +
     objDocument.documentElement.firstChild.nextSibling.firstChild.data;
  } else if (!objDocument.documentElement) {
    strError = 'String does not appear to be a valid XML fragment.';
  }
  if (strError) {
    Zapatec.Transport.displayError(0,
     'Error: Cannot parse.\n' + strError,
     onError);
  } else {
    if (typeof onLoad == 'function') {
      onLoad(objDocument);
    }
  }
};

Zapatec.Transport.serializeXmlDoc = function(objDocument) {
  if (window.XMLSerializer) {
    return (new XMLSerializer).serializeToString(objDocument);
  }
  if (objDocument.xml) {
    return objDocument.xml;
  }
};

Zapatec.Transport.fetchJsonObj = function(objArgs) {
  if (objArgs == null || typeof objArgs != 'object') {
    return null;
  }
  if (!objArgs.url) {
    return null;
  }
  if (typeof objArgs.async == 'undefined') {
    objArgs.async = true;
  }
  if (!objArgs.reliable) {
    objArgs.reliable = false;
  }
  var objFetchArgs = {};
  for (var strKey in objArgs) {
    objFetchArgs[strKey] = objArgs[strKey];
  }
  if (objArgs.async) {
    objFetchArgs.onLoad = function(objRequest) {
      Zapatec.Transport.parseJson({
        strJson: objRequest.responseText,
        reliable: objArgs.reliable,
        onLoad: objArgs.onLoad,
        onError: objArgs.onError
      });
    };
  } else {
    objFetchArgs.onLoad = null;
  }
  var objRequest = Zapatec.Transport.fetch(objFetchArgs);
  if (!objArgs.async && objRequest) {
    return Zapatec.Transport.parseJson({
      strJson: objRequest.responseText,
      reliable: objArgs.reliable,
      onLoad: objArgs.onLoad,
      onError: objArgs.onError
    });
  }
  return null;
};

Zapatec.Transport.parseJson = function(objArgs) {
  if (objArgs == null || typeof objArgs != 'object') {
    return null;
  }
  if (!objArgs.strJson) {
    return null;
  }
  if (!objArgs.reliable) {
    objArgs.reliable = false;
  }
  if (!objArgs.onLoad) {
    objArgs.onLoad = null;
  }
  if (!objArgs.onError) {
    objArgs.onError = null;
  }
  var objJson = null;
  try {
    if (objArgs.reliable) {
      objJson = eval('(' + objArgs.strJson + ')');
    } else {
      objJson = Zapatec.Transport.parseJsonStr(objArgs.strJson);
    }
  } catch (objException) {
    Zapatec.Transport.displayError(0,
     'Error: Cannot parse.\n' +
     'String does not appear to be a valid JSON fragment: ' +
     objException.message + '\n' + objException.text,
     objArgs.onError);
  };
  if (typeof objArgs.onLoad == 'function') {
    objArgs.onLoad(objJson);
  }
  return objJson;
};

Zapatec.Transport.parseJsonStr = function(text) {
  var p = /^\s*(([,:{}\[\]])|"(\\.|[^\x00-\x1f"\\])*"|-?\d+(\.\d*)?([eE][+-]?\d+)?|true|false|null)\s*/,
      token,
      operator;
  function error(m, t) {
      throw {
          name: 'JSONError',
          message: m,
          text: t || operator || token
      };
  }
  function next(b) {
      if (b && b != operator) {
          error("Expected '" + b + "'");
      }
      if (text) {
          var t = p.exec(text);
          if (t) {
              if (t[2]) {
                  token = null;
                  operator = t[2];
              } else {
                  operator = null;
                  try {
                      token = eval(t[1]);
                  } catch (e) {
                      error("Bad token", t[1]);
                  }
              }
              text = text.substring(t[0].length);
          } else {
              error("Unrecognized token", text);
          }
      } else {
          token = operator = null;
      }
  }
  function val() {
      var k, o;
      switch (operator) {
      case '{':
          next('{');
          o = {};
          if (operator != '}') {
              for (;;) {
                  if (operator || typeof token != 'string') {
                      error("Missing key");
                  }
                  k = token;
                  next();
                  next(':');
                  o[k] = val();
                  if (operator != ',') {
                      break;
                  }
                  next(',');
              }
          }
          next('}');
          return o;
      case '[':
          next('[');
          o = [];
          if (operator != ']') {
              for (;;) {
                  o.push(val());
                  if (operator != ',') {
                      break;
                  }
                  next(',');
              }
          }
          next(']');
          return o;
      default:
          if (operator !== null) {
              error("Missing value");
          }
          k = token;
          next();
          return k;
      }
  }
  next();
  return val();
};

Zapatec.Transport.serializeJsonObj = function(v) {
  var a = [];
  function e(s) {
      a[a.length] = s;
  }
  function g(x) {
      var c, i, l, v;
      switch (typeof x) {
      case 'object':
          if (x) {
              if (x instanceof Array) {
                  e('[');
                  l = a.length;
                  for (i = 0; i < x.length; i += 1) {
                      v = x[i];
                      if (typeof v != 'undefined' &&
                              typeof v != 'function') {
                          if (l < a.length) {
                              e(',');
                          }
                          g(v);
                      }
                  }
                  e(']');
                  return;
              } else if (typeof x.toString != 'undefined') {
                  e('{');
                  l = a.length;
                  for (i in x) {
                      v = x[i];
                      if (x.hasOwnProperty(i) &&
                              typeof v != 'undefined' &&
                              typeof v != 'function') {
                          if (l < a.length) {
                              e(',');
                          }
                          g(i);
                          e(':');
                          g(v);
                      }
                  }
                  return e('}');
              }
          }
          e('null');
          return;
      case 'number':
          e(isFinite(x) ? +x : 'null');
          return;
      case 'string':
          l = x.length;
          e('"');
          for (i = 0; i < l; i += 1) {
              c = x.charAt(i);
              if (c >= ' ') {
                  if (c == '\\' || c == '"') {
                      e('\\');
                  }
                  e(c);
              } else {
                  switch (c) {
                      case '\b':
                          e('\\b');
                          break;
                      case '\f':
                          e('\\f');
                          break;
                      case '\n':
                          e('\\n');
                          break;
                      case '\r':
                          e('\\r');
                          break;
                      case '\t':
                          e('\\t');
                          break;
                      default:
                          c = c.charCodeAt();
                          e('\\u00' + Math.floor(c / 16).toString(16) +
                              (c % 16).toString(16));
                  }
              }
          }
          e('"');
          return;
      case 'boolean':
          e(String(x));
          return;
      default:
          e('null');
          return;
      }
  }
  g(v);
  return a.join('');
};

Zapatec.Transport.displayError = function(iErrCode, strError, onError) {
  if (typeof onError == 'function') {
    onError({
      errorCode: iErrCode,
      errorDescription: strError
    });
  } else {
    alert(strError);
  }
};

Zapatec.Transport.translateUrl = function(objArgs) {
  if (!objArgs || !objArgs.url) {
    return null;
  }
  var arrFullUrl = objArgs.url.split('?', 2);
  var strUrl = arrFullUrl[0];
  if (strUrl.charAt(0) == '/' || strUrl.indexOf(':') >= 0) {
    return objArgs.url;
  }
  if (!objArgs.relativeTo) {
    objArgs.relativeTo = document.location.toString();
  }
  objArgs.relativeTo = objArgs.relativeTo.split("?", 2)[0];
  var arrUrl = strUrl.split('/');
  var arrRelativeTo = objArgs.relativeTo.split('/');
  arrRelativeTo.pop();
  for (var iToken = 0; iToken < arrUrl.length; iToken++) {
    var strToken = arrUrl[iToken];
    if (strToken == '..') {
      arrRelativeTo.pop();
    } else if (strToken != '.') {
      arrRelativeTo.push(strToken);
    }
  }
  arrFullUrl[0] = arrRelativeTo.join('/');
  return arrFullUrl.join('?');
};

Zapatec.Transport.loadedJS = {};

Zapatec.Transport.isLoadedJS = function(strUrl, strAbsoluteUrl) {
  if (typeof strAbsoluteUrl == 'undefined') {
    strAbsoluteUrl = Zapatec.Transport.translateUrl({url: strUrl});
  }
  if (Zapatec.Transport.loadedJS[strAbsoluteUrl]) {
    return true;
  }
  var arrScripts = document.getElementsByTagName('script');
  for (var iScript = 0; iScript < arrScripts.length; iScript++) {
    var strSrc = arrScripts[iScript].getAttribute('src') || '';
    if (strSrc == strUrl) {
      Zapatec.Transport.loadedJS[strAbsoluteUrl] = true;
      return true;
    }
  }
  return false;
};

Zapatec.Transport.getPath = function(strScriptFileName) {
  var arrScripts = document.getElementsByTagName('script');
  for (var iScript = arrScripts.length - 1; iScript >= 0; iScript--) {
    var strSrc = arrScripts[iScript].getAttribute('src') || '';
    var arrTokens = strSrc.split('/');
    var strLastToken = arrTokens.pop();
    if (strLastToken == strScriptFileName) {
      return arrTokens.join('/') + '/';
    }
  }
  for (var strSrc in Zapatec.Transport.loadedJS) {
    var arrTokens = strSrc.split('/');
    var strLastToken = arrTokens.pop();
    if (strLastToken == strScriptFileName) {
      return arrTokens.join('/') + '/';
    }
  }
  return '';
};

Zapatec.Transport.include = function(strSrc, boolForce) {
  var strAbsoluteUrl = Zapatec.Transport.translateUrl({url: strSrc});
  if (!boolForce && Zapatec.Transport.isLoadedJS(strSrc, strAbsoluteUrl)) {
    return;
  }
  document.write('<s' + 'cript type="text/javascript" src="' + strSrc +
   '"></s' + 'cript>');
  Zapatec.Transport.loadedJS[strAbsoluteUrl] = true;
};

Zapatec.Transport.includeJS = function(strSrc) {
  var objContainer = document.body;
  if (!objContainer) {
    objContainer = document.getElementsByTagName('body')[0];
    if (!objContainer) {
      objContainer = document;
    }
  }
  var objScript = document.createElement('script');
  objScript.type = 'text/javascript';
  objScript.src = strSrc;
  objContainer.appendChild(objScript);
};

Zapatec.Transport.loadJS = function(objArgs) {
  if (!(objArgs instanceof Object)) {
    return;
  }
  if (typeof objArgs.async == 'undefined') {
    objArgs.async = true;
  }
  var strUrl = null;
  if (objArgs.url) {
    strUrl = objArgs.url;
  } else if (objArgs.module) {
    var strRelativeModule = 'transport.js';
    if (objArgs.relativeModule) {
      strRelativeModule = objArgs.relativeModule + '.js';
    }
    strUrl = Zapatec.Transport.getPath(strRelativeModule) + objArgs.module +
     '.js';
  } else {
    return;
  }
  var strAbsoluteUrl = Zapatec.Transport.translateUrl({url: strUrl});
  if (!objArgs.onLoad) {
    objArgs.onLoad = null;
  }
  if (!objArgs.onError) {
    objArgs.onError = null;
  }
  if (!objArgs.force && Zapatec.Transport.isLoadedJS(strUrl, strAbsoluteUrl)) {
    if (typeof objArgs.onLoad == 'function') {
      objArgs.onLoad();
    }
    return;
  }
  Zapatec.Transport.fetch({
    url: strUrl,
    async: objArgs.async,
    onLoad: function(objRequest) {
      if (!Zapatec.Transport.loadedJS[strAbsoluteUrl]) {
        var arrTokens = strUrl.split('/');
        var strLastToken = arrTokens.pop();
        Zapatec.lastLoadedModule = arrTokens.join('/') + '/';
        var funcScripts = new Function(objRequest.responseText);
        funcScripts.call(window);
        Zapatec.lastLoadedModule = null;
        Zapatec.Transport.loadedJS[strAbsoluteUrl] = true;
      }
      if (typeof objArgs.onLoad == 'function') {
        objArgs.onLoad();
      }
    },
    onError: objArgs.onError
  });
};

Zapatec.Transport.includeCSS = function(strHref) {
  var objContainer = document.getElementsByTagName('body')[0];
  if (!objContainer) {
    return;
  }
  var objLink = document.createElement('link');
  objLink.setAttribute('rel', 'stylesheet');
  objLink.setAttribute('type', 'text/css');
  objLink.setAttribute('href', strHref);
  objContainer.appendChild(objLink);
};

Zapatec.Transport.loadedCss = {};

Zapatec.Transport.loadCss = function(objArgs) {
  if (!(objArgs instanceof Object)) {
    return;
  }
  if (!objArgs.url) {
    return;
  }
  if (typeof objArgs.async == 'undefined') {
    objArgs.async = true;
  }
  if (!objArgs.onLoad) {
    objArgs.onLoad = null;
  }
  if (!objArgs.onError) {
    objArgs.onError = null;
  }
  var strAbsoluteUrl = Zapatec.Transport.translateUrl({url: objArgs.url});
  if (!objArgs.force) {
    if (Zapatec.Transport.loadedCss[strAbsoluteUrl]) {
      if (typeof objArgs.onLoad == 'function') {
        objArgs.onLoad();
      }
      return;
    }
    var arrLinks = document.getElementsByTagName('link');
    for (var iLnk = 0; iLnk < arrLinks.length; iLnk++) {
      var strHref = arrLinks[iLnk].getAttribute('href') || '';
      if (strHref == objArgs.url) {
        Zapatec.Transport.loadedCss[strAbsoluteUrl] = true;
        if (typeof objArgs.onLoad == 'function') {
          objArgs.onLoad();
        }
        return;
      }
    }
  }
  Zapatec.Transport.loadJS({
    module: 'stylesheet',
    async: objArgs.async,
    onLoad: function() {
      Zapatec.Transport.fetch({
        url: objArgs.url,
        async: objArgs.async,
        onLoad: function(objRequest) {
          var strCss = objRequest.responseText;
          var arrResultCss = [];
          var arrImgUrls = [];
          var arrCssUrls = [];
          var iPos = 0;
          var iNextPos = strCss.indexOf('url(', iPos);
          while (iNextPos >= 0) {
            iNextPos += 4;
            var strToken = strCss.substring(iPos, iNextPos);
            var boolIsImport = /@import\s+url\($/.test(strToken);
            arrResultCss.push(strToken);
            iPos = iNextPos;
            iNextPos = strCss.indexOf(')', iPos);
            if (iNextPos >= 0) {
              var strImgUrl = strCss.substring(iPos, iNextPos);
              strImgUrl = strImgUrl.replace(/['"]/g, '');
              strImgUrl = Zapatec.Transport.translateUrl({
                url: strImgUrl,
                relativeTo: objArgs.url
              });
              strImgUrl = Zapatec.Transport.translateUrl({
                url: strImgUrl
              });
              arrResultCss.push(strImgUrl);
              if (boolIsImport) {
                arrCssUrls.push(strImgUrl);
              } else {
                arrImgUrls.push(strImgUrl);
              }
              iPos = iNextPos;
              iNextPos = strCss.indexOf('url(', iPos);
            }
          }
          arrResultCss.push(strCss.substr(iPos));
          strCss = arrResultCss.join('');
          Zapatec.Transport.loadCssList({
            urls: arrCssUrls,
            async: objArgs.async,
            onLoad: function() {
              var objStyleSheet = new Zapatec.StyleSheet();
              objStyleSheet.addParse(strCss);
              if (typeof objArgs.onLoad == 'function') {
                objArgs.onLoad();
              }
            }
          });
          Zapatec.Transport.loadedCss[strAbsoluteUrl] = true;
          Zapatec.Transport.preloadImages({
            urls: arrImgUrls,
            timeout: 60000
          });
        },
        onError: objArgs.onError
      });
    },
    onError: objArgs.onError
  });
};

Zapatec.Transport.loadCssList = function(objArgs) {
  if (!(objArgs instanceof Object)) {
    return;
  }
  if (typeof objArgs.async == 'undefined') {
    objArgs.async = true;
  }
  if (!objArgs.onLoad) {
    objArgs.onLoad = null;
  }
  if (!objArgs.onError) {
    objArgs.onError = null;
  }
  if (!objArgs.urls || !objArgs.urls.length) {
    if (typeof objArgs.onLoad == 'function') {
      objArgs.onLoad();
    }
    return;
  }
  var strUrl = objArgs.urls.shift();
  var funcOnLoad = function() {
    Zapatec.Transport.loadCssList({
      urls: objArgs.urls,
      async: objArgs.async,
      force: objArgs.force,
      onLoad: objArgs.onLoad,
      onError: objArgs.onError
    });
  };
  Zapatec.Transport.loadCss({
    url: strUrl,
    async: objArgs.async,
    force: objArgs.force,
    onLoad: funcOnLoad,
    onError: function(objError) {
      Zapatec.Transport.displayError(objError.errorCode,
       objError.errorDescription, objArgs.onError);
      funcOnLoad();
    }
  });
};

Zapatec.Transport.imagePreloads = [];

Zapatec.Transport.preloadImages = function(objArgs) {
  Zapatec.Transport.loadJS({
    module: 'preloadimages',
    onLoad: function() {
      Zapatec.Transport.imagePreloads.push(new Zapatec.PreloadImages(objArgs));
    }
  });
};
if (!window.Zapatec || (Zapatec && !Zapatec.include)) {
	alert("You need to include zapatec.js file!");
}
window.calendar = null;
try {
	Zapatec.Calendar.loadPrefs();
} catch(e) {};
Zapatec.Utils.addEvent(window, "load", Zapatec.Utils.checkActivation);
Zapatec.Calendar = function (firstDayOfWeek, dateStr, onSelected, onClose) {
	this.bShowHistoryEvent=false;
	this.activeDiv = null;
	this.currentDateEl = null;
	this.getDateStatus = null;
	this.getDateToolTip = null;
	this.getDateText = null;
	this.timeout = null;
	this.onSelected = onSelected || null;
	this.onClose = onClose || null;
	this.onFDOW = null;
	this.dragging = false;
	this.hidden = false;
	this.minYear = 1970;
	this.maxYear = 2050;
	this.minMonth = 0;
	this.maxMonth = 11;
	this.dateFormat = Zapatec.Calendar.i18n("DEF_DATE_FORMAT");
	this.ttDateFormat = Zapatec.Calendar.i18n("TT_DATE_FORMAT");
	this.historyDateFormat = "%B %d, %Y";
	this.isPopup = true;
	this.weekNumbers = true;
	this.noGrab = false;
	if (Zapatec.Calendar.prefs.fdow || (Zapatec.Calendar.prefs.fdow == 0)) {
		this.firstDayOfWeek = parseInt(Zapatec.Calendar.prefs.fdow, 10);
	}
	else {
		var fd = 0;
		if (typeof firstDayOfWeek == "number") {
			fd = firstDayOfWeek;
		} else if (typeof Zapatec.Calendar._FD == 'number') {
			fd = Zapatec.Calendar._FD;
		}
		this.firstDayOfWeek = fd;
	}
	this.showsOtherMonths = false;
	this.dateStr = dateStr;
	this.showsTime = false;
	this.sortOrder = "asc";
	this.time24 = true;
	this.timeInterval = null;
	this.yearStep = 2;
	this.hiliteToday = true;
	this.multiple = null;
	this.table = null;
	this.element = null;
	this.tbody = new Array();
	this.firstdayname = null;
	this.monthsCombo = null;
	this.hilitedMonth = null;
	this.activeMonth = null;
	this.yearsCombo = null;
	this.hilitedYear = null;
	this.activeYear = null;
	this.histCombo = null;
	this.hilitedHist = null;
	this.dateClicked = false;
	this.numberMonths = 1;
	this.controlMonth = 1;
	this.vertical = false;
	this.monthsInRow = 1;
	this.titles = new Array();
	this.rowsOfDayNames = new Array();
	this.helpButton = true;
	this.disableFdowClick = true;
	this.disableDrag = false;
	Zapatec.Calendar._initSDN();
};

Zapatec.Calendar._initSDN = function() {
	if (typeof Zapatec.Calendar._TT._SDN == "undefined") {
		if (typeof Zapatec.Calendar._TT._SDN_len == "undefined")
			Zapatec.Calendar._TT._SDN_len = 3;
		var ar = [];
		for (var i = 8; i > 0;) {
			ar[--i] = Zapatec.Calendar._TT._DN[i].substr(0, Zapatec.Calendar._TT._SDN_len);
		}
		Zapatec.Calendar._TT._SDN = ar;
		if (typeof Zapatec.Calendar._TT._SMN_len == "undefined")
			Zapatec.Calendar._TT._SMN_len = 3;
		ar = [];
		for (var i = 12; i > 0;) {
			ar[--i] = Zapatec.Calendar._TT._MN[i].substr(0, Zapatec.Calendar._TT._SMN_len);
		}
		Zapatec.Calendar._TT._SMN = ar;
	}
	if (typeof Zapatec.Calendar._TT.AMPM == "undefined") {
		Zapatec.Calendar._TT.AMPM = {am : "am", pm : "pm"};
	}
};

Zapatec.Calendar.i18n = function(str, type) {
	var tr = '';
	if (!type) {
		if (Zapatec.Calendar._TT)
			tr = Zapatec.Calendar._TT[str];
		if (!tr && Zapatec.Calendar._TT_en)
			tr = Zapatec.Calendar._TT_en[str];
	} else switch(type) {
	    case "dn"  : tr = Zapatec.Calendar._TT._DN[str];  break;
	    case "sdn" : tr = Zapatec.Calendar._TT._SDN[str]; break;
	    case "mn"  : tr = Zapatec.Calendar._TT._MN[str];  break;
	    case "smn" : tr = Zapatec.Calendar._TT._SMN[str]; break;
		case "ampm" : tr = Zapatec.Calendar._TT._AMPM[str]; break;
	}
	if (!tr) tr = "" + str;
	return tr;
};

Zapatec.Calendar._C = null;

Zapatec.Calendar.prefs = {
	fdow     : null,
	history  : "",
	sortOrder : "asc",
	hsize    : 9
};

Zapatec.Calendar.savePrefs = function() {
	Zapatec.Utils.writeCookie("ZP_CAL", Zapatec.Utils.makePref(this.prefs), null, '/', 30);
};

Zapatec.Calendar.loadPrefs = function() {
	var txt = Zapatec.Utils.getCookie("ZP_CAL"), tmp;
	if (txt) {
		tmp = Zapatec.Utils.loadPref(txt);
		if (tmp)
			Zapatec.Utils.mergeObjects(this.prefs, tmp);
	}
};

Zapatec.Calendar._add_evs = function(el) {
	var C = Zapatec.Calendar;
	Zapatec.Utils.addEvent(el, "mouseover", C.dayMouseOver);
	Zapatec.Utils.addEvent(el, "mousedown", C.dayMouseDown);
	Zapatec.Utils.addEvent(el, "mouseout", C.dayMouseOut);
	if (Zapatec.is_ie)
		Zapatec.Utils.addEvent(el, "dblclick", C.dayMouseDblClick);
};

Zapatec.Calendar._del_evs = function(el) {
	var C = this;
	Zapatec.Utils.removeEvent(el, "mouseover", C.dayMouseOver);
	Zapatec.Utils.removeEvent(el, "mousedown", C.dayMouseDown);
	Zapatec.Utils.removeEvent(el, "mouseout", C.dayMouseOut);
	if (Zapatec.is_ie)
		Zapatec.Utils.removeEvent(el, "dblclick", C.dayMouseDblClick);
};

Zapatec.Calendar.findMonth = function(el) {
	if (typeof el.month != "undefined") {
		return el;
	} else if (el.parentNode && typeof el.parentNode.month != "undefined") {
		return el.parentNode;
	}
	return null;
};

Zapatec.Calendar.findHist = function(el) {
	if (typeof el.histDate != "undefined") {
		return el;
	} else if (el.parentNode && typeof el.parentNode.histDate != "undefined") {
		return el.parentNode;
	}
	return null;
};

Zapatec.Calendar.findYear = function(el) {
	if (typeof el.year != "undefined") {
		return el;
	} else if (el.parentNode && typeof el.parentNode.year != "undefined") {
		return el.parentNode;
	}
	return null;
};

Zapatec.Calendar.showMonthsCombo = function () {
	var cal = Zapatec.Calendar._C;
	if (!cal) {
		return false;
	}
	var cd = cal.activeDiv;
	var mc = cal.monthsCombo;
	var date = cal.date,
		MM = cal.date.getMonth(),
		YY = cal.date.getFullYear(),
		min = (YY == cal.minYear),
		max = (YY == cal.maxYear);
	for (var i = mc.firstChild; i; i = i.nextSibling) {
		var m = i.month;
		Zapatec.Utils.removeClass(i, "hilite");
		Zapatec.Utils.removeClass(i, "active");
		Zapatec.Utils.removeClass(i, "disabled");
		i.disabled = false;
		if ((min && m < cal.minMonth) ||
		    (max && m > cal.maxMonth)) {
			Zapatec.Utils.addClass(i, "disabled");
			i.disabled = true;
		}
		if (m == MM)
			Zapatec.Utils.addClass(cal.activeMonth = i, "active");
	}
	var s = mc.style;
	s.display = "block";
	if (cd.navtype < 0)
		s.left = cd.offsetLeft + "px";
	else {
		var mcw = mc.offsetWidth;
		if (typeof mcw == "undefined")
			mcw = 50;
		s.left = (cd.offsetLeft + cd.offsetWidth - mcw) + "px";
	}
	s.top = (cd.offsetTop + cd.offsetHeight) + "px";
	cal.updateWCH(mc);
};

Zapatec.Calendar.showHistoryCombo = function() {
	var cal = Zapatec.Calendar._C, a, h, i, cd, hc, s, tmp, div;
	if (!cal)
		return false;
	hc = cal.histCombo;
	while (hc.firstChild)
		hc.removeChild(hc.lastChild);
	if (Zapatec.Calendar.prefs.history) {
		a = Zapatec.Calendar.prefs.history.split(/,/);
		i = 0;
		while (tmp = a[i++]) {
			tmp = tmp.split(/\//);
			h = Zapatec.Utils.createElement("div");
			h.className = Zapatec.is_ie ? "label-IEfix" : "label";
			h.histDate = new Date(parseInt(tmp[0], 10), parseInt(tmp[1], 10)-1, parseInt(tmp[2], 10),
					      tmp[3] ? parseInt(tmp[3], 10) : 0,
					      tmp[4] ? parseInt(tmp[4], 10) : 0);
			h.appendChild(window.document.createTextNode(h.histDate.print(cal.historyDateFormat)));
			hc.appendChild(h);
			if (h.histDate.dateEqualsTo(cal.date))
				Zapatec.Utils.addClass(h, "active");
		}
	}
	cd = cal.activeDiv;
	s = hc.style;
	s.display = "block";
	s.left = Math.floor(cd.offsetLeft + (cd.offsetWidth-hc.offsetWidth)/2) + "px";
	s.top = (cd.offsetTop + cd.offsetHeight) + "px";
	cal.updateWCH(hc);
	cal.bEventShowHistory=true;
};

Zapatec.Calendar.showYearsCombo = function (fwd) {
	var cal = Zapatec.Calendar._C;
	if (!cal) {
		return false;
	}
	var cd = cal.activeDiv;
	var yc = cal.yearsCombo;
	if (cal.hilitedYear) {
		Zapatec.Utils.removeClass(cal.hilitedYear, "hilite");
	}
	if (cal.activeYear) {
		Zapatec.Utils.removeClass(cal.activeYear, "active");
	}
	cal.activeYear = null;
	var Y = cal.date.getFullYear() + (fwd ? 1 : -1);
	var yr = yc.firstChild;
	var show = false;
	for (var i = 12; i > 0; --i) {
		if (Y >= cal.minYear && Y <= cal.maxYear) {
			yr.firstChild.data = Y;
			yr.year = Y;
			yr.style.display = "block";
			show = true;
		} else {
			yr.style.display = "none";
		}
		yr = yr.nextSibling;
		Y += fwd ? cal.yearStep : -cal.yearStep;
	}
	if (show) {
		var s = yc.style;
		s.display = "block";
		if (cd.navtype < 0)
			s.left = cd.offsetLeft + "px";
		else {
			var ycw = yc.offsetWidth;
			if (typeof ycw == "undefined")
				ycw = 50;
			s.left = (cd.offsetLeft + cd.offsetWidth - ycw) + "px";
		}
		s.top = (cd.offsetTop + cd.offsetHeight) + "px";
	}
	cal.updateWCH(yc);
};

Zapatec.Calendar.tableMouseUp = function(ev) {
	var cal = Zapatec.Calendar._C;
	if (!cal) {
		return false;
	}
	if (cal.timeout) {
		clearTimeout(cal.timeout);
	}
	var el = cal.activeDiv;
	if (!el) {
		return false;
	}
	var target = Zapatec.Utils.getTargetElement(ev);
	if (typeof(el.navtype) == "undefined") {
		while(target && !target.calendar) {
			target = target.parentNode;
		}	
	}
	ev || (ev = window.event);
	Zapatec.Utils.removeClass(el, "active");
	if (target == el || target.parentNode == el) {
		Zapatec.Calendar.cellClick(el, ev);
	}
	var mon = Zapatec.Calendar.findMonth(target);
	var date = null;
	if (mon) {
		if (!mon.disabled) {
			date = new Date(cal.date);
			if (mon.month != date.getMonth()) {
				date.setMonth(mon.month);
				cal.setDate(date, true);
				cal.dateClicked = false;
				cal.callHandler();
			}
		}
	} else {
		var year = Zapatec.Calendar.findYear(target);
		if (year) {
			date = new Date(cal.date);
			if (year.year != date.getFullYear()) {
				date.setFullYear(year.year);
				cal.setDate(date, true);
				cal.dateClicked = false;
				cal.callHandler();
			}
		} else {
			var hist = Zapatec.Calendar.findHist(target);
			if (hist && !hist.histDate.dateEqualsTo(cal.date)) {
				date = new Date(hist.histDate);
				cal._init(cal.firstDayOfWeek, cal.date = date);
				cal.dateClicked = false;
				cal.callHandler();
				cal.updateHistory();
			}
		}
	}
	Zapatec.Utils.removeEvent(window.document, "mouseup", Zapatec.Calendar.tableMouseUp);
	Zapatec.Utils.removeEvent(window.document, "mouseover", Zapatec.Calendar.tableMouseOver);
	Zapatec.Utils.removeEvent(window.document, "mousemove", Zapatec.Calendar.tableMouseOver);
	cal._hideCombos();
	Zapatec.Calendar._C = null;
	return Zapatec.Utils.stopEvent(ev);
};

Zapatec.Calendar.tableMouseOver = function (ev) {
	var cal = Zapatec.Calendar._C;
	if (!cal) {
		return;
	}
	var el = cal.activeDiv;
	var target = Zapatec.Utils.getTargetElement(ev);
	if (target == el || target.parentNode == el) {
		Zapatec.Utils.addClass(el, "hilite active");
		Zapatec.Utils.addClass(el.parentNode, "rowhilite");
	} else {
		if (typeof el.navtype == "undefined" ||
		    (el.navtype != 50 && ((el.navtype == 0 && !cal.histCombo) || Math.abs(el.navtype) > 2)))
			Zapatec.Utils.removeClass(el, "active");
		Zapatec.Utils.removeClass(el, "hilite");
		Zapatec.Utils.removeClass(el.parentNode, "rowhilite");
	}
	ev || (ev = window.event);
	if (el.navtype == 50 && target != el) {
		var pos = Zapatec.Utils.getAbsolutePos(el);
		var w = el.offsetWidth;
		var x = ev.clientX;
		var dx;
		var decrease = true;
		if (x > pos.x + w) {
			dx = x - pos.x - w;
			decrease = false;
		} else
			dx = pos.x - x;
		if (dx < 0) dx = 0;
		var range = el._range;
		var current = el._current;
		var date = cal.currentDate;
		var pm = (date.getHours() >= 12);
		var old = el.firstChild.data;
		var count = Math.floor(dx / 10) % range.length;
		for (var i = range.length; --i >= 0;)
			if (range[i] == current)
				break;
		while (count-- > 0)
			if (decrease) {
				if (--i < 0) {
					i = range.length - 1;
				}
			} else if ( ++i >= range.length ) {
				i = 0;
			}

		if (cal.getDateStatus) { 
			var minute = null;
			var hour = null;
			var new_date = new Date(date);
			if (el.className.indexOf("ampm", 0) != -1) {
			   minute = date.getMinutes();
			   if (old != range[i]) {
			      hour = (range[i] == Zapatec.Calendar.i18n("pm", "ampm")) ? ((date.getHours() == 0) ? (12) : (date.getHours() + 12)) : (date.getHours() - 12);
			   } else {
			      hour = date.getHours();
			   }
			   new_date.setHours(hour);
			}
			if (el.className.indexOf("hour", 0) != -1) {
			   minute = date.getMinutes();
			   hour = (!cal.time24) ? ((pm) ? ((range[i] != 12) ? (parseInt(range[i], 10) + 12) : (12)) : ((range[i] != 12) ? (range[i]) : (0))) : (range[i]); // new value of hours
			   new_date.setHours(hour);
			}
			if (el.className.indexOf("minute", 0) != -1) {
				hour = date.getHours();
				minute = range[i];
				new_date.setMinutes(minute);
			}
		}
		var status = false;
		if (cal.getDateStatus) {
		   status = cal.getDateStatus(new_date, date.getFullYear(), date.getMonth(), date.getDate(), parseInt(hour, 10), parseInt(minute, 10));
		}
		if (status == false) {
		   if ( !((!cal.time24) && (range[i] == Zapatec.Calendar.i18n("pm", "ampm")) && (hour > 23)) ) {
		      el.firstChild.data = range[i];
		   }
		}
		cal.onUpdateTime();
	}
	var mon = Zapatec.Calendar.findMonth(target);
	if (mon) {
		if (!mon.disabled) {
			if (mon.month != cal.date.getMonth()) {
				if (cal.hilitedMonth) {
					Zapatec.Utils.removeClass(cal.hilitedMonth, "hilite");
				}
				Zapatec.Utils.addClass(mon, "hilite");
				cal.hilitedMonth = mon;
			} else if (cal.hilitedMonth) {
				Zapatec.Utils.removeClass(cal.hilitedMonth, "hilite");
			}
		}
	} else {
		if (cal.hilitedMonth) {
			Zapatec.Utils.removeClass(cal.hilitedMonth, "hilite");
		}
		var year = Zapatec.Calendar.findYear(target);
		if (year) {
			if (year.year != cal.date.getFullYear()) {
				if (cal.hilitedYear) {
					Zapatec.Utils.removeClass(cal.hilitedYear, "hilite");
				}
				Zapatec.Utils.addClass(year, "hilite");
				cal.hilitedYear = year;
			} else if (cal.hilitedYear) {
				Zapatec.Utils.removeClass(cal.hilitedYear, "hilite");
			}
		} else {
			if (cal.hilitedYear) {
				Zapatec.Utils.removeClass(cal.hilitedYear, "hilite");
			}
			var hist = Zapatec.Calendar.findHist(target);
			if (hist) {
				if (!hist.histDate.dateEqualsTo(cal.date)) {
					if (cal.hilitedHist) {
						Zapatec.Utils.removeClass(cal.hilitedHist, "hilite");
					}
					Zapatec.Utils.addClass(hist, "hilite");
					cal.hilitedHist = hist;
				} else if (cal.hilitedHist) {
					Zapatec.Utils.removeClass(cal.hilitedHist, "hilite");
				}
			} else if (cal.hilitedHist) {
				Zapatec.Utils.removeClass(cal.hilitedHist, "hilite");
			}
		}
	}
	return Zapatec.Utils.stopEvent(ev);
};

Zapatec.Calendar.tableMouseDown = function (ev) {
	if (Zapatec.Utils.getTargetElement(ev) == Zapatec.Utils.getElement(ev)) {
		return Zapatec.Utils.stopEvent(ev);
	}
};

Zapatec.Calendar.calDragIt = function (ev) {
	ev || (ev = window.event);
	var cal = Zapatec.Calendar._C;
	if (!cal.disableDrag) {
		if (!(cal && cal.dragging)) {
			return false;
		}
		var posX = ev.clientX + window.document.body.scrollLeft;
		var posY = ev.clientY + window.document.body.scrollTop;
		cal.hideShowCovered();
		var st = cal.element.style, L = posX - cal.xOffs, T = posY - cal.yOffs;
		st.left = L + "px";
		st.top = T + "px";
		Zapatec.Utils.setupWCH(cal.WCH, L, T);
	}
	return Zapatec.Utils.stopEvent(ev);
};

Zapatec.Calendar.calDragEnd = function (ev) {
	var cal = Zapatec.Calendar._C;
	if (!cal) {
		return false;
	}
	cal.dragging = false;
	Zapatec.Utils.removeEvent(window.document, "mousemove", Zapatec.Calendar.calDragIt);
	Zapatec.Utils.removeEvent(window.document, "mouseover", Zapatec.Calendar.calDragIt);
	Zapatec.Utils.removeEvent(window.document, "mouseup", Zapatec.Calendar.calDragEnd);
	Zapatec.Calendar.tableMouseUp(ev);
	cal.hideShowCovered();
};

Zapatec.Calendar.dayMouseDown = function(ev) {
	var canDrag = true;
	var el = Zapatec.Utils.getElement(ev);
	if (el.className.indexOf("disabled") != -1 || el.className.indexOf("true") != -1) {
		return false;
	}
	var cal = el.calendar;
	while(!cal) {
		el = el.parentNode;
		cal = el.calendar;
	}	
	cal.bEventShowHistory=false;
	cal.activeDiv = el;
	Zapatec.Calendar._C = cal;
	if (el.navtype != 300) {
		if (el.navtype == 50) {
			if (!((cal.timeInterval == null) || ((cal.timeInterval < 60) && (el.className.indexOf("hour", 0) != -1)))) {canDrag = false;}
			el._current = el.firstChild.data;
			if (canDrag) {Zapatec.Utils.addEvent(window.document, "mousemove", Zapatec.Calendar.tableMouseOver);}
		} else {
			if (((el.navtype == 201) || (el.navtype == 202)) && (cal.timeInterval > 30) && (el.timePart.className.indexOf("minute", 0) != -1)) {canDrag = false;}
			if (canDrag) {Zapatec.Utils.addEvent(window.document, Zapatec.is_ie5 ? "mousemove" : "mouseover", Zapatec.Calendar.tableMouseOver);}
		}
		if (canDrag) {Zapatec.Utils.addClass(el, "hilite active");}
		Zapatec.Utils.addEvent(window.document, "mouseup", Zapatec.Calendar.tableMouseUp);
	} else if (cal.isPopup) {
		cal._dragStart(ev);
	} else {
		Zapatec.Calendar._C = null;
	}
	if (el.navtype == -1 || el.navtype == 1) {
		if (cal.timeout) clearTimeout(cal.timeout);
		cal.timeout = setTimeout("Zapatec.Calendar.showMonthsCombo()", 250);
	} else if (el.navtype == -2 || el.navtype == 2) {
		if (cal.timeout) clearTimeout(cal.timeout);
		cal.timeout = setTimeout((el.navtype > 0) ? "Zapatec.Calendar.showYearsCombo(true)" : "Zapatec.Calendar.showYearsCombo(false)", 250);
	} else if (el.navtype == 0 && Zapatec.Calendar.prefs.history) {
		if (cal.timeout) clearTimeout(cal.timeout);
		cal.timeout = setTimeout("Zapatec.Calendar.showHistoryCombo()", 250);
	} else {
		cal.timeout = null;
	}
	return Zapatec.Utils.stopEvent(ev);
};

Zapatec.Calendar.dayMouseDblClick = function(ev) {
	Zapatec.Calendar.cellClick(Zapatec.Utils.getElement(ev), ev || window.event);
	if (Zapatec.is_ie)
		window.document.selection.empty();
};

Zapatec.Calendar.dayMouseOver = function(ev) {
	var el = Zapatec.Utils.getElement(ev),
		caldate = el.caldate;
	while (!el.calendar) {
		el = el.parentNode;
		caldate = el.caldate;
	}
	var cal = el.calendar;
	var cel = el.timePart;
	if (caldate) {
		caldate = new Date(caldate[0], caldate[1], caldate[2]);
		if (caldate.getDate() != el.caldate[2]) caldate.setDate(el.caldate[2]);
	}
	if (Zapatec.Utils.isRelated(el, ev) || Zapatec.Calendar._C || el.className.indexOf("disabled") != -1 || el.className.indexOf("true") != -1) {
		return false;
	}
	if (el.ttip) {
		if (el.ttip.substr(0, 1) == "_") {
			el.ttip = caldate.print(el.calendar.ttDateFormat) + el.ttip.substr(1);
		}
		el.calendar.showHint(el.ttip);
	}
	if (el.navtype != 300) {
		if (!((cal.timeInterval == null) || (el.className.indexOf("ampm", 0) != -1) || ((cal.timeInterval < 60) && (el.className.indexOf("hour", 0) != -1))) && (el.navtype == 50)) {return Zapatec.Utils.stopEvent(ev);}
		if (((el.navtype == 201) || (el.navtype == 202)) && (cal.timeInterval > 30) && (cel.className.indexOf("minute", 0) != -1)) {return Zapatec.Utils.stopEvent(ev);}
		Zapatec.Utils.addClass(el, "hilite");
		if (caldate) {
			Zapatec.Utils.addClass(el.parentNode, "rowhilite");
		}
	}
	return Zapatec.Utils.stopEvent(ev);
};

Zapatec.Calendar.dayMouseOut = function(ev) {
	var el = Zapatec.Utils.getElement(ev);
	while (!el.calendar) {
		el = el.parentNode;
		caldate = el.caldate;
	}
	if (Zapatec.Utils.isRelated(el, ev) || Zapatec.Calendar._C || el.className.indexOf("disabled") != -1 || el.className.indexOf("true") != -1)
		return false;
	Zapatec.Utils.removeClass(el, "hilite");
	if (el.caldate)
		Zapatec.Utils.removeClass(el.parentNode, "rowhilite");
	if (el.calendar)
		el.calendar.showHint(Zapatec.Calendar.i18n("SEL_DATE"));
	return Zapatec.Utils.stopEvent(ev);
};

Zapatec.Calendar.cellClick = function(el, ev) {
	var cal = el.calendar;
	var closing = false;
	var newdate = false;
	var date = null;
	while(!cal) {
		el = el.parentNode;
		cal = el.calendar;
	}
	if (el.className.indexOf("disabled") != -1 || el.className.indexOf("true") != -1) {
		return false;
	}
	if (typeof el.navtype == "undefined") {
		if (cal.currentDateEl) {
			Zapatec.Utils.removeClass(cal.currentDateEl, "selected");
			Zapatec.Utils.addClass(el, "selected");
			closing = (cal.currentDateEl == el);
			if (!closing) {
				cal.currentDateEl = el;
			}
		}
		var tmpDate = new Date(el.caldate[0], el.caldate[1], el.caldate[2]);
		if (tmpDate.getDate() != el.caldate[2]) {
			tmpDate.setDate(el.caldate[2]);
		}
		cal.date.setDateOnly(tmpDate);
		cal.currentDate.setDateOnly(tmpDate);
		date = cal.date;
		var other_month = !(cal.dateClicked = !el.otherMonth);
		if (!other_month && cal.multiple)
			cal._toggleMultipleDate(new Date(date));
		newdate = true;
		if (other_month)
			cal._init(cal.firstDayOfWeek, date);
		cal.onSetTime();
	} else {
		if (el.navtype == 200) {
			Zapatec.Utils.removeClass(el, "hilite");
			cal.callCloseHandler();
			return;
		}
		date = new Date(cal.date);
		if (el.navtype == 0 && !cal.bEventShowHistory)
			date.setDateOnly(new Date());
		cal.dateClicked = false;
		var year = date.getFullYear();
		var mon = date.getMonth();
		function setMonth(m) {
			var day = date.getDate();
			var max = date.getMonthDays(m);
			if (day > max) {
				date.setDate(max);
			}
			date.setMonth(m);
		};
		switch (el.navtype) {
		    case 400:
			Zapatec.Utils.removeClass(el, "hilite");
			var text = Zapatec.Calendar.i18n("ABOUT");
			if (typeof text != "undefined") {
				text += cal.showsTime ? Zapatec.Calendar.i18n("ABOUT_TIME") : "";
			} else {
				text = "";
			}
			alert(text);
			return;
		    case -2:
			if (year > cal.minYear) {
				date.setFullYear(year - 1);
			}
			break;
		    case -1:
			if (mon > 0) {
				setMonth(mon - 1);
			} else if (year-- > cal.minYear) {
				date.setFullYear(year);
				setMonth(11);
			}
			break;
		    case 1:
			if (mon < 11) {
				setMonth(mon + 1);
			} else if (year < cal.maxYear) {
				date.setFullYear(year + 1);
				setMonth(0);
			}
			break;
		    case 2:
			if (year < cal.maxYear) {
				date.setFullYear(year + 1);
			}
			break;
		    case 100:
			cal.setFirstDayOfWeek(el.fdow);
			Zapatec.Calendar.prefs.fdow = cal.firstDayOfWeek;
			Zapatec.Calendar.savePrefs();
			if (cal.onFDOW)
				cal.onFDOW(cal.firstDayOfWeek);
			return;
		    case 50:
			var date = cal.currentDate;
			if (el.className.indexOf("ampm", 0) >= 0)
				;
			else
			if (!((cal.timeInterval == null) || ((cal.timeInterval < 60) && (el.className.indexOf("hour", 0) != -1)))) {break;}
			var range = el._range;
			var current = el.firstChild.data;
			var pm = (date.getHours() >= 12);
			for (var i = range.length; --i >= 0;)
				if (range[i] == current)
					break;
			if (ev && ev.shiftKey) {
				if (--i < 0) {
					i = range.length - 1;
				}
			} else if ( ++i >= range.length ) {
					i = 0;
				}
			if (cal.getDateStatus) {
				var minute = null;
				var hour = null;
				var new_date = new Date(date);
				if (el.className.indexOf("ampm", 0) != -1) {
					minute = date.getMinutes();
					hour = (range[i] == Zapatec.Calendar.i18n("pm", "ampm")) ? ((date.getHours() == 12) ? (date.getHours()) : (date.getHours() + 12)) : (date.getHours() - 12);
					if ( cal.getDateStatus && cal.getDateStatus(new_date, date.getFullYear(), date.getMonth(), date.getDate(), parseInt(hour, 10), parseInt(minute, 10)) ) {
					   var dirrect;
					   if (range[i] == Zapatec.Calendar.i18n("pm", "ampm")) {
					      dirrect = -5;
					   } else {
					      dirrect = 5;
					   }
					   hours = hour;
					   minutes = minute;
					   do {
					      minutes += dirrect;
					      if (minutes >=60) {
						 minutes -= 60;
						 ++hours;
						 if (hours >= 24) hours -= 24;
						 new_date.setHours(hours);
					      }
					      if (minutes < 0) {
						 minutes += 60;
						 --hours;
					  	 if (hours < 0) hours += 24;
						 new_date.setHours(hours);
					      }
					      new_date.setMinutes(minutes);
					      if (!cal.getDateStatus(new_date, date.getFullYear(), date.getMonth(), date.getDate(), parseInt(hours, 10), parseInt(minutes, 10))) {
						 hour = hours;
						 minute = minutes;
						 if (hour > 12) i = 1; else i = 0;
						 cal.date.setHours(hour);
						 cal.date.setMinutes(minute);
						 cal.onSetTime();
					      }
					   } while ((hour != hours) || (minute != minutes));
					}
					new_date.setHours(hour);
				}
				if (el.className.indexOf("hour", 0) != -1) {
				   minute = date.getMinutes();
				   hour = (!cal.time24) ? ((pm) ? ((range[i] != 12) ? (parseInt(range[i], 10) + 12) : (12)) : ((range[i] != 12) ? (range[i]) : (0))) : (range[i]);  // new value of hours
				   new_date.setHours(hour);
				}
				if (el.className.indexOf("minute", 0) != -1) {
				   hour = date.getHours();
				   minute = range[i];
				   new_date.setMinutes(minute);
				}
			}
			var status = false;
			if (cal.getDateStatus) {
			   status = cal.getDateStatus(new_date, date.getFullYear(), date.getMonth(), date.getDate(), parseInt(hour, 10), parseInt(minute, 10));
			}
			if (!status) {
			   el.firstChild.data = range[i];
			}
			cal.onUpdateTime();
			return;
		    case 201:
		    case 202:
			var cel = el.timePart;
			var date = cal.currentDate;
			if ((cel.className.indexOf("minute", 0) != -1) && (cal.timeInterval > 30)) {break;}
			var val = parseInt(cel.firstChild.data, 10);
			var pm = (date.getHours() >= 12);
			var range = cel._range;
			for (var i = range.length; --i >= 0;)
				if (val == range[i]) {
					val = i;
					break;
				}
			var step = cel._step;
			if (el.navtype == 201) {
				val = step*Math.floor(val/step);
				val += step;
				if (val >= range.length)
					val = 0;
			} else {
				val = step*Math.ceil(val/step);
				val -= step;
				if (val < 0)
					val = range.length-step;
			}
			if (cal.getDateStatus) { 
			   var minute = null;
			   var hour = null;
			   var new_date = new Date(date);
			   if (cel.className == "hour") {
			      minute = date.getMinutes();
			      hour = (!cal.time24) ? ((pm) ? ((range[val] != 12) ? (parseInt(range[val], 10) + 12) : (12)) : ((range[val] != 12) ? (range[val]) : (0))) : (range[val]);
			      new_date.setHours(hour);
			   }
			   if (cel.className == "minute") {
			      hour = date.getHours();
			      minute = val;
			      new_date.setMinutes(range[val]);
			   }
			}
			var status = false;
			if (cal.getDateStatus) {
			   status = cal.getDateStatus(new_date, date.getFullYear(), date.getMonth(), date.getDate(), parseInt(hour, 10), parseInt(minute, 10));
			}   
			if (!status) {
			   cel.firstChild.data = range[val];
			}
			cal.onUpdateTime();
			return;
		    case 0:
			if (cal.getDateStatus && ((cal.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate()) == true) || (cal.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate()) == "disabled"))) {
				return false;
			}
			break;
		}
		if (!date.equalsTo(cal.date)) {
			if ((el.navtype >= -2 && el.navtype <=2) && (el.navtype != 0)) {
				cal._init(cal.firstDayOfWeek, date, true);
				return;
			}
			cal.setDate(date);
			newdate = !(el.navtype && (el.navtype >= -2 && el.navtype <=2));
		}
	}
	if (newdate) {
		cal.callHandler();
	}
	if (closing) {
		Zapatec.Utils.removeClass(el, "hilite");
		cal.callCloseHandler();
	}
};

Zapatec.Calendar.prototype.create = function (_par) {
	var parent = null;
	if (! _par) {
		parent = window.document.getElementsByTagName("body")[0];
		this.isPopup = true;
		this.WCH = Zapatec.Utils.createWCH();
	} else {
		parent = _par;
		this.isPopup = false;
	}
	this.currentDate = this.date = this.dateStr ? new Date(this.dateStr) : new Date();
	var table = Zapatec.Utils.createElement("table");
	this.table = table;
	table.cellSpacing = 0;
	table.cellPadding = 0;
	table.calendar = this;
	Zapatec.Utils.addEvent(table, "mousedown", Zapatec.Calendar.tableMouseDown);
	var div = Zapatec.Utils.createElement("div");
	this.element = div;
	div.className = "calendar";
	if (Zapatec.is_opera) {
		table.style.width = (this.monthsInRow * ((this.weekNumbers) ? (8) : (7)) * 2 + 4.4 * this.monthsInRow) + "em";
	}
	if (this.isPopup) {
		div.style.position = "absolute";
		div.style.display = "none";
	}
	div.appendChild(table);
	var cell = null;
	var row = null;
	var cal = this;
	var hh = function (text, cs, navtype) {
		cell = Zapatec.Utils.createElement("td", row);
		cell.colSpan = cs;
		cell.className = "calendarbutton";
		if (Math.abs(navtype) <= 2)
			cell.className += " nav";
		Zapatec.Calendar._add_evs(cell);
		cell.calendar = cal;
		cell.navtype = navtype;
		if (text.substr(0, 1) != "&") {
			cell.appendChild(document.createTextNode(text));
		}
		else {
			cell.innerHTML = text;
		}
		return cell;
	};
	var title_length = ((this.weekNumbers) ? (8) : (7)) * this.monthsInRow - 2;
	var thead = Zapatec.Utils.createElement("thead", table);
	if (this.numberMonths == 1) {
		this.title = thead;
	}
	row = Zapatec.Utils.createElement("tr", thead);
	if (this.helpButton) {
		hh("?", 1, 400).ttip = Zapatec.Calendar.i18n("INFO");
	} else {
		cell = Zapatec.Utils.createElement("td", row);
		cell.colSpan = 1;
		cell.className = "calendarbutton";
		cell.innerHTML = "<p>&nbsp</p>";
	}
	this.title = hh("", title_length, 300);
	this.title.className = "title";
	if (this.isPopup) {
		if (!this.disableDrag) {
			this.title.ttip = Zapatec.Calendar.i18n("DRAG_TO_MOVE");
			this.title.style.cursor = "move";
		}
		hh("&#x00d7;", 1, 200).ttip = Zapatec.Calendar.i18n("CLOSE");
	} else {
		cell = Zapatec.Utils.createElement("td", row);
		cell.colSpan = 1;
		cell.className = "calendarbutton";
		cell.innerHTML = "<p>&nbsp</p>";
	}
	row = Zapatec.Utils.createElement("tr", thead);
	this._nav_py = hh("&#x00ab;", 1, -2);
	this._nav_py.ttip = Zapatec.Calendar.i18n("PREV_YEAR");
	this._nav_pm = hh("&#x2039;", 1, -1);
	this._nav_pm.ttip = Zapatec.Calendar.i18n("PREV_MONTH");
	this._nav_now = hh(Zapatec.Calendar.i18n("TODAY"), title_length - 2, 0);
	this._nav_now.ttip = Zapatec.Calendar.i18n("GO_TODAY");
	this._nav_nm = hh("&#x203a;", 1, 1);
	this._nav_nm.ttip = Zapatec.Calendar.i18n("NEXT_MONTH");
	this._nav_ny = hh("&#x00bb;", 1, 2);
	this._nav_ny.ttip = Zapatec.Calendar.i18n("NEXT_YEAR");
	var rowsOfMonths = Math.floor(this.numberMonths / this.monthsInRow);
	if (this.numberMonths % this.monthsInRow > 0) {
		++rowsOfMonths;
	}
	for (var l = 1; l <= rowsOfMonths; ++l) {
		var thead = Zapatec.Utils.createElement("thead", table);
		if (Zapatec.is_opera) {thead.style.display = "table-row-group";}
		if (this.numberMonths != 1) {
			row = Zapatec.Utils.createElement("tr", thead);
			var title_length = 5;
			this.weekNumbers && ++title_length;
			this.titles[l] = new Array();
			for (var k = 1; (k <= this.monthsInRow) && ((l - 1) * this.monthsInRow + k <= this.numberMonths); ++k) {
				cell = Zapatec.Utils.createElement("td", row);
				cell.colSpan = 1;
				cell.className = "calendarbutton";
				cell.innerHTML = "<p>&nbsp</p>";
				this.titles[l][k] = hh("", title_length, 300);
				this.titles[l][k].className = "title";
				cell = Zapatec.Utils.createElement("td", row);
				cell.colSpan = 1;
				cell.className = "calendarbutton";
				cell.innerHTML = "<p>&nbsp</p>";
			}
		}
		row = Zapatec.Utils.createElement("tr", thead);
		row.className = "daynames";
		for (k = 1; (k <= this.monthsInRow) && ((l - 1) * this.monthsInRow + k <= this.numberMonths); ++k) {
			if (this.weekNumbers) {
				cell = Zapatec.Utils.createElement("td", row);
				cell.className = "name wn";
				cell.appendChild(window.document.createTextNode(Zapatec.Calendar.i18n("WK")));
				if (k > 1) {
					Zapatec.Utils.addClass(cell, "month-left-border");
				}
				var cal_wk = Zapatec.Calendar.i18n("WK")
					if (cal_wk == null) {
						cal_wk = "";
					}
			}
			for (var i = 7; i > 0; --i) {
				cell = Zapatec.Utils.createElement("td", row);
				cell.appendChild(window.document.createTextNode(""));
			}
		}
		this.firstdayname = row.childNodes[this.weekNumbers?1:0];
		this.rowsOfDayNames[l] = this.firstdayname; 
		this._displayWeekdays();
		var tbody = Zapatec.Utils.createElement("tbody", table);
		this.tbody[l] = tbody;
		for (i = 6; i > 0; --i) {
			row = Zapatec.Utils.createElement("tr", tbody);
			for (k = 1; (k <= this.monthsInRow) && ((l - 1) * this.monthsInRow + k <= this.numberMonths); ++k) {
				if (this.weekNumbers) {
					cell = Zapatec.Utils.createElement("td", row);
					cell.appendChild(document.createTextNode(""));
				}
				for (var j = 7; j > 0; --j) {
					cell = Zapatec.Utils.createElement("td", row);
					cell.appendChild(document.createTextNode(""));
					cell.calendar = this;
					Zapatec.Calendar._add_evs(cell);
				}
			}
		}
	}
	var tfoot = Zapatec.Utils.createElement("tfoot", table);
	if (this.showsTime) {
		row = Zapatec.Utils.createElement("tr", tfoot);
		row.className = "time";
		var emptyColspan;
		if (this.monthsInRow != 1) {
			cell = Zapatec.Utils.createElement("td", row);
			emptyColspan = cell.colSpan = Math.ceil((((this.weekNumbers) ? 8 : 7) * (this.monthsInRow - 1)) / 2);
			cell.className = "timetext";
			cell.innerHTML = "&nbsp";
		}						
		cell = Zapatec.Utils.createElement("td", row);
		cell.className = "timetext";
		cell.colSpan = this.weekNumbers ? 2 : 1;
		cell.innerHTML = Zapatec.Calendar.i18n("TIME") || "&nbsp;";
		(function() {
			function makeTimePart(className, init, range_start, range_end) {
				var table, tbody, tr, tr2, part;
				if (range_end) {
					cell = Zapatec.Utils.createElement("td", row);
					cell.colSpan = 1;
					if (cal.showsTime != "seconds") {
						++cell.colSpan;
					}
					cell.className = "parent-" + className;
					table = Zapatec.Utils.createElement("table", cell);
					table.cellSpacing = table.cellPadding = 0;
					if (className == "hour")
						table.align = "right";
					table.className = "calendar-time-scroller";
					tbody = Zapatec.Utils.createElement("tbody", table);
					tr    = Zapatec.Utils.createElement("tr", tbody);
					tr2   = Zapatec.Utils.createElement("tr", tbody);
				} else
					tr = row;
				part = Zapatec.Utils.createElement("td", tr);
				part.className = className;
				part.appendChild(window.document.createTextNode(init));
				part.calendar = cal;
				part.ttip = Zapatec.Calendar.i18n("TIME_PART");
				part.navtype = 50;
				part._range = [];
				if (!range_end)
					part._range = range_start;
				else {
					part.rowSpan = 2;
					for (var i = range_start; i <= range_end; ++i) {
						var txt;
						if (i < 10 && range_end >= 10) txt = '0' + i;
						else txt = '' + i;
						part._range[part._range.length] = txt;
					}
					var up = Zapatec.Utils.createElement("td", tr);
					up.className = "up";
					up.navtype = 201;
					up.calendar = cal;
					up.timePart = part;
					if (Zapatec.is_khtml)
						up.innerHTML = "&nbsp;";
					Zapatec.Calendar._add_evs(up);
					var down = Zapatec.Utils.createElement("td", tr2);
					down.className = "down";
					down.navtype = 202;
					down.calendar = cal;
					down.timePart = part;
					if (Zapatec.is_khtml)
						down.innerHTML = "&nbsp;";
					Zapatec.Calendar._add_evs(down);
				}
				Zapatec.Calendar._add_evs(part);
				return part;
			};
			var hrs = cal.currentDate.getHours();
			var mins = cal.currentDate.getMinutes();
			if (cal.showsTime == "seconds") {
				var secs = cal.currentDate.getSeconds();
			}
			var t12 = !cal.time24;
			var pm = (hrs > 12);
			if (t12 && pm) hrs -= 12;
			var H = makeTimePart("hour", hrs, t12 ? 1 : 0, t12 ? 12 : 23);
			H._step = (cal.timeInterval > 30) ? (cal.timeInterval / 60) : 1;
			cell = Zapatec.Utils.createElement("td", row);
			cell.innerHTML = ":";
			cell.className = "colon";
			var M = makeTimePart("minute", mins, 0, 59);
			M._step = ((cal.timeInterval) && (cal.timeInterval < 60)) ? (cal.timeInterval) : 5; // FIXME: make this part configurable
			if (cal.showsTime == "seconds") {
				cell = Zapatec.Utils.createElement("td", row);
				cell.innerHTML = ":";
				cell.className = "colon";
				var S = makeTimePart("minute", secs, 0, 59);
				S._step = 5;
			}
			var AP = null;
			if (t12) {
				AP = makeTimePart("ampm", pm ? Zapatec.Calendar.i18n("pm", "ampm") : Zapatec.Calendar.i18n("am", "ampm"), [Zapatec.Calendar.i18n("am", "ampm"), Zapatec.Calendar.i18n("pm", "ampm")]);
				AP.className += " calendarbutton";
			} else
				Zapatec.Utils.createElement("td", row).innerHTML = "&nbsp;";
			cal.onSetTime = function() {
				var hrs = this.currentDate.getHours();
				var mins = this.currentDate.getMinutes();
				if (this.showsTime == "seconds") {
					var secs = cal.currentDate.getSeconds();
				}
				if (this.timeInterval) {
					mins += this.timeInterval - ((mins - 1 + this.timeInterval) % this.timeInterval) - 1;
				}
				while (mins >= 60) {
					mins -= 60;
					++hrs;
				}
				if (this.timeInterval > 60) {
					var interval = this.timeInterval / 60;
					if (hrs % interval != 0) {
						hrs += interval - ((hrs - 1 + interval) % interval) - 1;
					}
					if (hrs >= 24) {hrs -= 24;}
				}
				var new_date = new Date(this.currentDate);
				if (this.getDateStatus && this.getDateStatus(this.currentDate, this.currentDate.getFullYear(), this.currentDate.getMonth(), this.currentDate.getDate(), hrs, mins)) {
				   hours = hrs;
				   minutes = mins;
				   do {
				     if (this.timeInterval) {
					 	if (this.timeInterval < 60) {
							minutes += this.timeInterval;
						} else {
							hrs += this.timeInterval / 60;
						}
					 } else {
					 	minutes += 5;
					 }
				     if (minutes >=60) {
						minutes -= 60;
						hours += 1;
				     }
				     if (hours >= 24) {hours -= 24;}
					 new_date.setMinutes(minutes);
				     new_date.setHours(hours);
				     if (!this.getDateStatus(new_date, this.currentDate.getFullYear(), this.currentDate.getMonth(), this.currentDate.getDate(), hours, minutes)) {
					 	hrs = hours;
				 	 	mins = minutes;
				     }
				   } while ((hrs != hours) || (mins != minutes));
				}
				this.currentDate.setMinutes(mins);
				this.currentDate.setHours(hrs);
				var pm = (hrs >= 12);
				if (pm && t12 && hrs != 12) hrs -= 12;
				if (!pm && t12 && hrs == 0) hrs = 12;
				H.firstChild.data = (hrs < 10) ? ("0" + hrs) : hrs;
				M.firstChild.data = (mins < 10) ? ("0" + mins) : mins;
				if (this.showsTime == "seconds") {
					S.firstChild.data = (secs < 10) ? ("0" + secs) : secs;
				}
				if (t12)
				   AP.firstChild.data = pm ? Zapatec.Calendar.i18n("pm", "ampm") : Zapatec.Calendar.i18n("am", "ampm");
			};
			cal.onUpdateTime = function() {
				var date = this.currentDate;
				var h = parseInt(H.firstChild.data, 10);
				if (t12) {
					if (/pm/i.test(AP.firstChild.data) && h < 12)
						h += 12;
					else if (/am/i.test(AP.firstChild.data) && h == 12)
						h = 0;
				}
				var d = date.getDate();
				var m = date.getMonth();
				var y = date.getFullYear();
				date.setHours(h);
				date.setMinutes(parseInt(M.firstChild.data, 10));
				if (this.showsTime == "seconds") {
					date.setSeconds(parseInt(S.firstChild.data, 10));
				}
				date.setFullYear(y);
				date.setMonth(m);
				date.setDate(d);
				this.dateClicked = false;
				this.callHandler();
			};
		})();
		if (this.monthsInRow != 1) {
			cell = Zapatec.Utils.createElement("td", row);
			cell.colSpan = ((this.weekNumbers) ? 8 : 7) * (this.monthsInRow - 1) - Math.ceil(emptyColspan);
			cell.className = "timetext";
			cell.innerHTML = "&nbsp";
		}						
	} else {
		this.onSetTime = this.onUpdateTime = function() {};
	}
	row = Zapatec.Utils.createElement("tr", tfoot);
	row.className = "footrow";
	cell = hh(Zapatec.Calendar.i18n("SEL_DATE"), this.weekNumbers ? (8 * this.numberMonths) : (7 * this.numberMonths), 300);
	cell.className = "ttip";
	if (this.isPopup && !this.disableDrag) {
		cell.ttip = Zapatec.Calendar.i18n("DRAG_TO_MOVE");
		cell.style.cursor = "move";
	}
	this.tooltips = cell;
	div = this.monthsCombo = Zapatec.Utils.createElement("div", this.element);
	div.className = "combo";
	for (i = 0; i < 12; ++i) {
		var mn = Zapatec.Utils.createElement("div");
		mn.className = Zapatec.is_ie ? "label-IEfix" : "label";
		mn.month = i;
		mn.appendChild(window.document.createTextNode(Zapatec.Calendar.i18n(i, "smn")));
		div.appendChild(mn);
	}
	div = this.yearsCombo = Zapatec.Utils.createElement("div", this.element);
	div.className = "combo";
	for (i = 12; i > 0; --i) {
		var yr = Zapatec.Utils.createElement("div");
		yr.className = Zapatec.is_ie ? "label-IEfix" : "label";
		yr.appendChild(window.document.createTextNode(""));
		div.appendChild(yr);
	}
	div = this.histCombo = Zapatec.Utils.createElement("div", this.element);
	div.className = "combo history";
	this._init(this.firstDayOfWeek, this.date);
	parent.appendChild(this.element);
};

Zapatec.Calendar._keyEvent = function(ev) {
	if (!window.calendar) {
		return false;
	}
	(Zapatec.is_ie) && (ev = window.event);
	var cal = window.calendar;
	var act = (Zapatec.is_ie || ev.type == "keypress");
	var K = ev.keyCode;
	var date  = new Date(cal.date);
	if (ev.ctrlKey) {
		switch (K) {
		    case 37:
			act && Zapatec.Calendar.cellClick(cal._nav_pm);
			break;
		    case 38:
			act && Zapatec.Calendar.cellClick(cal._nav_py);
			break;
		    case 39:
			act && Zapatec.Calendar.cellClick(cal._nav_nm);
			break;
		    case 40:
			act && Zapatec.Calendar.cellClick(cal._nav_ny);
			break;
		    default:
			return false;
		}
	} else switch (K) {
	    case 32:
		Zapatec.Calendar.cellClick(cal._nav_now);
		break;
	    case 27:
		act && cal.callCloseHandler();
		break;
		case 37:
			if (act && !cal.multiple) {
				date.setTime(date.getTime() - 86400000);
				cal.setDate(date);
			}
			break;
	    case 38:
			if (act && !cal.multiple) {
				date.setTime(date.getTime() - 7 * 86400000);
				cal.setDate(date);
			}
			break;
	    case 39:
			if (act && !cal.multiple) {
				date.setTime(date.getTime() + 86400000);
				cal.setDate(date);
			}
			break;
	    case 40:
			if (act && !cal.multiple) {
				date.setTime(date.getTime() + 7 * 86400000);
				cal.setDate(date);
			}
			break;
	    case 13:
		if (act) {
			Zapatec.Calendar.cellClick(cal.currentDateEl);
		}
		break;
	    default:
		return false;
	}
	return Zapatec.Utils.stopEvent(ev);
};

Zapatec.Calendar.prototype._init = function (firstDayOfWeek, date, last) {
	var
		today = new Date(),
		TD = today.getDate(),
		TY = today.getFullYear(),
		TM = today.getMonth();
	if (this.getDateStatus && !last) {
		var status = this.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate());
		var backupDate = new Date(date);
		while (((status == true) || (status == "disabled")) && (backupDate.getMonth() == date.getMonth())) {
			date.setTime(date.getTime() + 86400000);
			var status = this.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate());
		}
		if (backupDate.getMonth() != date.getMonth()) {
			date = new Date(backupDate);
			while (((status == true) || (status == "disabled")) && (backupDate.getMonth() == date.getMonth())) {
				date.setTime(date.getTime() - 86400000);
				var status = this.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate());
			}
		}
		if (backupDate.getMonth() != date.getMonth()) {
			last = true;
			date = new Date(backupDate);
		}
	}
	var year = date.getFullYear();
	var month = date.getMonth();
	var rowsOfMonths = Math.floor(this.numberMonths / this.monthsInRow);
	var minMonth;
	var diffMonth, last_row, before_control;
	if (!this.vertical) {
		diffMonth = (this.controlMonth - 1);
		minMonth = month - diffMonth;
	} else {
		last_row = ((this.numberMonths - 1) % this.monthsInRow) + 1;
		before_control = (this.controlMonth - 1) % this.monthsInRow;
		bottom = (before_control >= (last_row) ? (last_row) : (before_control));
		diffMonth = (before_control) * (rowsOfMonths - 1) + Math.floor((this.controlMonth - 1) / this.monthsInRow) + bottom;
		minMonth = month - diffMonth;
	}
	var minYear = year;
	if (minMonth < 0) {
		minMonth += 12;
		--minYear;
	}
	var maxMonth = minMonth + this.numberMonths - 1;
	var maxYear = minYear;
	if (maxMonth > 11) {
		maxMonth -= 12;
		++maxYear;
	}
	function disableControl(ctrl) {
		Zapatec.Calendar._del_evs(ctrl);
		ctrl.disabled = true;
		ctrl.className = "calendarbutton";
		ctrl.innerHTML = "<p>&nbsp</p>";
	}
	function enableControl(ctrl, sign) {
		Zapatec.Calendar._add_evs(ctrl);
		ctrl.disabled = false;
		ctrl.className = "button nav";
		ctrl.innerHTML = sign;
	}
	if (minYear <= this.minYear) {
		if (!this._nav_py.disabled) {
			disableControl(this._nav_py);
		}
	} else {
		if (this._nav_py.disabled) {	
			enableControl(this._nav_py, "&#x00ab;");
		}
	}
	if (maxYear >= this.maxYear) {
		if (!this._nav_ny.disabled) {
			disableControl(this._nav_ny);
		}
	} else {
		if (this._nav_ny.disabled) {
			enableControl(this._nav_ny, "&#x00bb;");
		}
	}
	if (((minYear == this.minYear) && (minMonth <= this.minMonth)) || (minYear < this.minYear)) {
		if (!this._nav_pm.disabled) {
			disableControl(this._nav_pm);
		}
	} else {
		if (this._nav_pm.disabled) {	
			enableControl(this._nav_pm, "&#x2039;");
		}
	}
	if (((maxYear == this.maxYear) && (maxMonth >= this.maxMonth)) || (maxYear > this.maxYear)) {
		if (!this._nav_nm.disabled) {
			disableControl(this._nav_nm);
		}
	} else {
		if (this._nav_nm.disabled) {	
			enableControl(this._nav_nm, "&#x203a;");
		}
	}
	upperMonth = this.maxMonth + 1;
	upperYear = this.maxYear;
	if (upperMonth > 11) {
		upperMonth -= 12;
		++upperYear;
	}
	bottomMonth = this.minMonth - 1;
	bottomYear = this.minYear;
	if (bottomMonth < 0) {
		bottomMonth += 12;
		--bottomYear;
	}
	maxDate1 = new Date(maxYear, maxMonth, date.getMonthDays(maxMonth), 23, 59, 59, 999);
	maxDate2 = new Date(upperYear, upperMonth, 1, 0, 0, 0, 0);
	minDate1 = new Date(minYear, minMonth, 1, 0, 0, 0, 0);
	minDate2 = new Date(bottomYear, bottomMonth, date.getMonthDays(bottomMonth), 23, 59, 59, 999);
	if (maxDate1.getTime() > maxDate2.getTime()) {
		date.setTime(date.getTime() - (maxDate1.getTime() - maxDate2.getTime()));
	}
	if (minDate1.getTime() < minDate2.getTime()) {
		date.setTime(date.getTime() + (minDate2.getTime() - minDate1.getTime()));
	}
	delete maxDate1; delete maxDate2; delete minDate1; delete minDate2;
	this.firstDayOfWeek = firstDayOfWeek;
	if (!last) {
		this.currentDate = date;
	}
	this.date = date;
	(this.date = new Date(this.date)).setDateOnly(date);
	year = this.date.getFullYear();
	month = this.date.getMonth();
	var initMonth = date.getMonth();
	var mday = this.date.getDate();
	var no_days = date.getMonthDays();
	var months = new Array();
	if (this.numberMonths % this.monthsInRow > 0) {
		++rowsOfMonths;
	}
	for (var l = 1; l <= rowsOfMonths; ++l) {
		months[l] = new Array();
		for (var k = 1; (k <= this.monthsInRow) && ((l - 1) * this.monthsInRow + k <= this.numberMonths); ++k) {
			var tmpDate = new Date(date);
			if (this.vertical) {
				var validMonth = date.getMonth() - diffMonth + ((k - 1) * (rowsOfMonths - 1) + (l - 1) + ((last_row < k) ? (last_row) : (k - 1)));
			} else {
				var validMonth = date.getMonth() - diffMonth + (l - 1) * this.monthsInRow + k - 1;
			}
			if (validMonth < 0) {
				tmpDate.setFullYear(tmpDate.getFullYear() - 1);
				validMonth = 12 + validMonth;
			}
			if (validMonth > 11) {
				tmpDate.setFullYear(tmpDate.getFullYear() + 1);
				validMonth = validMonth - 12;
			}
			tmpDate.setDate(1);
			tmpDate.setMonth(validMonth);
			var day1 = (tmpDate.getDay() - this.firstDayOfWeek) % 7;
			if (day1 < 0)
				day1 += 7;
			var hrs = tmpDate.getHours();
			tmpDate.setDate(-day1);
			tmpDate.setDate(tmpDate.getDate() + 1);
			if (hrs != tmpDate.getHours()) {
				tmpDate.setDate(1);
				tmpDate.setMonth(validMonth);
				tmpDate.setDate(-day1);
				tmpDate.setDate(tmpDate.getDate() + 1);
			}
			months[l][k] = tmpDate;
		}
	}
	var MN = Zapatec.Calendar.i18n(month, "smn");
	var weekend = Zapatec.Calendar.i18n("WEEKEND");
	var dates = this.multiple ? (this.datesCells = {}) : null;
	var DATETXT = this.getDateText;
	for (var l = 1; l <= rowsOfMonths; ++l) {
		var row = this.tbody[l].firstChild;
		for (var i = 7; --i > 0; row = row.nextSibling) {
			var cell = row.firstChild;
			var hasdays = false;
			for (var k = 1; (k <= this.monthsInRow) && ((l - 1) * this.monthsInRow + k <= this.numberMonths); ++k) {
				date = months[l][k];
				if (this.weekNumbers) {
					cell.className = " day wn";
					cell.innerHTML = date.getWeekNumber();
					if (k > 1) {
						Zapatec.Utils.addClass(cell, "month-left-border");
					}
					cell = cell.nextSibling;
				}
				row.className = "daysrow";
				var iday;
				for (j = 7; cell && (iday = date.getDate()) && (j > 0); date.setDate(iday+1), ((date.getDate() == iday) ? (date.setHours(1) && date.setDate(iday + 1)) : (false)), cell = cell.nextSibling, --j) {
					var
						wday = date.getDay(),
						dmonth = date.getMonth(),
						dyear = date.getFullYear();
					cell.className = " day";
					if ((!this.weekNumbers) && (j == 7) && (k != 1)) {
						Zapatec.Utils.addClass(cell, "month-left-border");
					}
					if ((j == 1) && (k != this.monthsInRow)) {
						Zapatec.Utils.addClass(cell, "month-right-border");
					}
					if (this.vertical) {
						validMonth = initMonth - diffMonth + ((k - 1) * (rowsOfMonths - 1) + (l - 1) + ((last_row < k) ? (last_row) : (k - 1)));
					} else {
						validMonth = initMonth - diffMonth + ((l - 1) * this.monthsInRow + k - 1);
					}
					if (validMonth < 0) {
						validMonth = 12 + validMonth;
					}
					if (validMonth > 11) {
						validMonth = validMonth - 12;
					}
					var current_month = !(cell.otherMonth = !(dmonth == validMonth));
					if (!current_month) {
						if (this.showsOtherMonths)
							cell.className += " othermonth";
						else {
							cell.className += " true";
							cell.innerHTML = "<p style='margin : 0px; padding : 0px;'>&nbsp;</p>";
							continue;
						}
					} else
						hasdays = true;
					cell.innerHTML = DATETXT ? DATETXT(date, dyear, dmonth, iday) : iday;
					dates && (dates[date.print("%Y%m%d")] = cell);
					if (this.getDateStatus) {
						var status = this.getDateStatus(date, dyear, dmonth, iday);
						if (this.getDateToolTip) {
							var toolTip = this.getDateToolTip(date, dyear, dmonth, iday);
							if (toolTip)
								cell.title = toolTip;
						}
						if (status == true) {
							cell.className += " disabled";
						} else {
							cell.className += " " + status;
						}
					}
					if (!cell.disabled) {
						cell.caldate = [dyear, dmonth, iday];
						cell.ttip = "_";
						if (!this.multiple && current_month && iday == this.currentDate.getDate() && this.hiliteToday && (dmonth == this.currentDate.getMonth()) && (dyear == this.currentDate.getFullYear())) {
							cell.className += " selected";
							this.currentDateEl = cell;
						}
						if (dyear == TY && dmonth == TM && iday == TD) {
							cell.className += " today";
							cell.ttip += Zapatec.Calendar.i18n("PART_TODAY");
						}
						if ((weekend != null) && (weekend.indexOf(wday.toString()) != -1)) {
							cell.className += cell.otherMonth ? " oweekend" : " weekend";
						}
					}
				}
				if (!(hasdays || this.showsOtherMonths))
					row.className = "emptyrow";
			}
			if ((i == 1) && (l < rowsOfMonths)) {
				if (row.className == "emptyrow") {
					row = row.previousSibling;
				}
				cell = row.firstChild;
				while (cell != null) {
					Zapatec.Utils.addClass(cell, "month-bottom-border");
					cell = cell.nextSibling;
				}
			}
		}
	}
	if (this.numberMonths == 1) {
		this.title.innerHTML = Zapatec.Calendar.i18n(month, "mn") + ", " + year;
      if (this.params && this.params.titleHtml)
         if (typeof this.params.titleHtml == 'function')
            this.title.innerHTML = this.params.titleHtml(this.title.innerHTML, month, year)
         else
           this.title.innerHTML += this.params.titleHtml
	} else {
      if (this.params && this.params.titleHtml)
         if (typeof this.params.titleHtml == 'function')
            this.title.innerHTML = this.params.titleHtml(Zapatec.Calendar.i18n(month, "mn") + ", " + year, month, year)
         else
           this.title.innerHTML = this.params.titleHtml
		for (var l = 1; l <= rowsOfMonths; ++l) {
			for (var k = 1; (k <= this.monthsInRow) && ((l - 1) * this.monthsInRow + k <= this.numberMonths); ++k) {
				if (this.vertical) {
					validMonth = month - diffMonth + ((k - 1) * (rowsOfMonths - 1) + (l - 1) + ((last_row < k) ? (last_row) : (k - 1)));
				} else {
					validMonth = month - diffMonth + (l - 1) * this.monthsInRow + k - 1;
				}
				validYear = year;
				if (validMonth < 0) {
					--validYear;
					validMonth = 12 + validMonth;
				}
				if (validMonth > 11) {
					++validYear;
					validMonth = validMonth - 12;
				}
				this.titles[l][k].innerHTML = Zapatec.Calendar.i18n(validMonth, "mn") + ", " + validYear;
			}
		}
	}	
	this.onSetTime();
	this._initMultipleDates();
	this.updateWCH();
};

Zapatec.Calendar.prototype._initMultipleDates = function() {
	if (this.multiple) {
		for (var i in this.multiple) {
			var cell = this.datesCells[i];
			var d = this.multiple[i];
			if (!d)
				continue;
			if (cell)
				cell.className += " selected";
		}
	}
};

Zapatec.Calendar.prototype._toggleMultipleDate = function(date) {
	if (this.multiple) {
		var ds = date.print("%Y%m%d");
		var cell = this.datesCells[ds];
		if (cell) {
			var d = this.multiple[ds];
			if (!d) {
				Zapatec.Utils.addClass(cell, "selected");
				this.multiple[ds] = date;
			} else {
				Zapatec.Utils.removeClass(cell, "selected");
				delete this.multiple[ds];
			}
		}
	}
};

Zapatec.Calendar.prototype.setDateToolTipHandler = function (unaryFunction) {
	this.getDateToolTip = unaryFunction;
};

Zapatec.Calendar.prototype.setDate = function (date, justInit) {
	if (!date)
		date = new Date();
	if (!date.equalsTo(this.date)) {
		var year = date.getFullYear(), m = date.getMonth();
		if (year == this.minYear && m < this.minMonth)
			this.showHint("<div class='error'>" + Zapatec.Calendar.i18n("E_RANGE") + " </div>");
		else if (year == this.maxYear && m > this.maxMonth)
			this.showHint("<div class='error'> " + Zapatec.Calendar.i18n("E_RANGE") + "</div>");
		this._init(this.firstDayOfWeek, date, justInit);
	}
};

Zapatec.Calendar.prototype.showHint = function(text) {
	this.tooltips.innerHTML = text;
};

Zapatec.Calendar.prototype.reinit = function() {
	this._init(this.firstDayOfWeek, this.date);
};

Zapatec.Calendar.prototype.refresh = function() {
	var p = this.isPopup ? null : this.element.parentNode;
	var x = parseInt(this.element.style.left);
	var y = parseInt(this.element.style.top);
	this.destroy();
	this.dateStr = this.date;
	this.create(p);
	if (this.isPopup)
		this.showAt(x, y);
	else
		this.show();
};

Zapatec.Calendar.prototype.setFirstDayOfWeek = function (firstDayOfWeek) {
	if (this.firstDayOfWeek != firstDayOfWeek) {
		this._init(firstDayOfWeek, this.date);
		var rowsOfMonths = Math.floor(this.numberMonths / this.monthsInRow);
		if (this.numberMonths % this.monthsInRow > 0) {
			++rowsOfMonths;
		}
		for (var l = 1; l <= rowsOfMonths; ++l) {
			this.firstdayname = this.rowsOfDayNames[l];
			this._displayWeekdays();
		}		
	}
};

Zapatec.Calendar.prototype.setDateStatusHandler = Zapatec.Calendar.prototype.setDisabledHandler = function (unaryFunction) {
	this.getDateStatus = unaryFunction;
};

Zapatec.Calendar.prototype.setRange = function (A, Z) {
	var m,
		a = Math.min(A, Z),
		z = Math.max(A, Z);
	this.minYear = m = Math.floor(a);
	this.minMonth = (m == a) ? 0 : Math.ceil((a-m)*100-1);
	this.maxYear = m = Math.floor(z);
	this.maxMonth = (m == z) ? 11 : Math.ceil((z-m)*100-1);
};

Zapatec.Calendar.prototype.setMultipleDates = function(multiple) {
	if (!multiple || typeof multiple == "undefined") return;
	this.multiple = {};
	for (var i = multiple.length; --i >= 0;) {
	    var d = multiple[i];
	    var ds = d.print("%Y%m%d");
	    this.multiple[ds] = d;
	}
};

Zapatec.Calendar.prototype.submitFlatDates = function()
{
	if (typeof this.params.flatCallback == "function") {
	   Zapatec.Utils.sortOrder = (this.sortOrder!="asc" && this.sortOrder!="desc" && this.sortOrder!="none") ? "none" : this.sortOrder;
	   if ( this.multiple && (Zapatec.Utils.sortOrder != "none") ) {
			var dateArray = new Array();
			for (var i in this.multiple) {
				var currentDate = this.multiple[i];
				if (currentDate) {
					dateArray[dateArray.length] = currentDate;
				}
			    dateArray.sort(Zapatec.Utils.compareDates);
			}
			this.multiple = {};
			for (var i = 0; i < dateArray.length; i++) {
				var d = dateArray[i];
				var ds = d.print("%Y%m%d");
				this.multiple[ds] = d;
			}
	   }
	   this.params.flatCallback(this);
	}
}

Zapatec.Calendar.prototype.callHandler = function () {
	if (this.onSelected) {
		this.onSelected(this, this.date.print(this.dateFormat));
	}
};

Zapatec.Calendar.prototype.updateHistory = function () {
	var a, i, d, tmp, s, str = "", len = Zapatec.Calendar.prefs.hsize - 1;
	if (Zapatec.Calendar.prefs.history) {
		a = Zapatec.Calendar.prefs.history.split(/,/);
		i = 0;
		while (i < len && (tmp = a[i++])) {
			s = tmp.split(/\//);
			d = new Date(parseInt(s[0], 10), parseInt(s[1], 10)-1, parseInt(s[2], 10),
				     parseInt(s[3], 10), parseInt(s[4], 10));
			if (!d.dateEqualsTo(this.date))
				str += "," + tmp;
		}
	}
	Zapatec.Calendar.prefs.history = this.date.print("%Y/%m/%d/%H/%M") + str;
	Zapatec.Calendar.savePrefs();
};

Zapatec.Calendar.prototype.callCloseHandler = function () {
	if (this.dateClicked) {
		this.updateHistory();
	}
	if (this.onClose) {
		this.onClose(this);
	}
	this.hideShowCovered();
};

Zapatec.Calendar.prototype.destroy = function () {
	this.hide();
	Zapatec.Utils.destroy(this.element);
	Zapatec.Utils.destroy(this.WCH);
	Zapatec.Calendar._C = null;
	window.calendar = null;
};

Zapatec.Calendar.prototype.reparent = function (new_parent) {
	var el = this.element;
	el.parentNode.removeChild(el);
	new_parent.appendChild(el);
};

Zapatec.Calendar._checkCalendar = function(ev) {
	if (!window.calendar) {
		return false;
	}
	var el = Zapatec.is_ie ? Zapatec.Utils.getElement(ev) : Zapatec.Utils.getTargetElement(ev);
	for (; el != null && el != calendar.element; el = el.parentNode);
	if (el == null) {
		window.calendar.callCloseHandler();
		return Zapatec.Utils.stopEvent(ev);
	}
};

Zapatec.Calendar.prototype.updateWCH = function(other_el) {
	Zapatec.Utils.setupWCH_el(this.WCH, this.element, other_el);
};

Zapatec.Calendar.prototype.show = function () {
	var rows = this.table.getElementsByTagName("tr");
	for (var i = rows.length; i > 0;) {
		var row = rows[--i];
		Zapatec.Utils.removeClass(row, "rowhilite");
		var cells = row.getElementsByTagName("td");
		for (var j = cells.length; j > 0;) {
			var cell = cells[--j];
			Zapatec.Utils.removeClass(cell, "hilite");
			Zapatec.Utils.removeClass(cell, "active");
		}
	}
	this.element.style.display = "block";
	this.hidden = false;
	if (this.isPopup) {
		this.updateWCH();
		window.calendar = this;
		if (!this.noGrab) {
			Zapatec.Utils.addEvent(window.document, "keydown", Zapatec.Calendar._keyEvent);
			Zapatec.Utils.addEvent(window.document, "keypress", Zapatec.Calendar._keyEvent);
			Zapatec.Utils.addEvent(window.document, "mousedown", Zapatec.Calendar._checkCalendar);
		}
	}
	this.hideShowCovered();
};

Zapatec.Calendar.prototype.hide = function () {
	if (this.isPopup) {
		Zapatec.Utils.removeEvent(window.document, "keydown", Zapatec.Calendar._keyEvent);
		Zapatec.Utils.removeEvent(window.document, "keypress", Zapatec.Calendar._keyEvent);
		Zapatec.Utils.removeEvent(window.document, "mousedown", Zapatec.Calendar._checkCalendar);
	}
	this.element.style.display = "none";
	Zapatec.Utils.hideWCH(this.WCH);
	this.hidden = true;
	this.hideShowCovered();
};

Zapatec.Calendar.prototype.showAt = function (x, y) {
	var s = this.element.style;
	s.left = x + "px";
	s.top = y + "px";
	this.show();
};

Zapatec.Calendar.prototype.showAtElement = function (el, opts) {
	var self = this;
	var p = Zapatec.Utils.getAbsolutePos(el);
	if (!opts || typeof opts != "string") {
		this.showAt(p.x, p.y + el.offsetHeight);
		return true;
	}
	this.element.style.display = "block";
	var w = self.element.offsetWidth;
	var h = self.element.offsetHeight;
	self.element.style.display = "none";
	var valign = opts.substr(0, 1);
	var halign = "l";
	if (opts.length > 1) {
		halign = opts.substr(1, 1);
	}
	switch (valign) {
	    case "T": p.y -= h; break;
	    case "B": p.y += el.offsetHeight; break;
	    case "C": p.y += (el.offsetHeight - h) / 2; break;
	    case "t": p.y += el.offsetHeight - h; break;
	    case "b": break;
	}
	switch (halign) {
	    case "L": p.x -= w; break;
	    case "R": p.x += el.offsetWidth; break;
	    case "C": p.x += (el.offsetWidth - w) / 2; break;
	    case "l": p.x += el.offsetWidth - w; break;
	    case "r": break;
	}
	p.width = w;
	p.height = h + 40;
	self.monthsCombo.style.display = "none";
	Zapatec.Utils.fixBoxPosition(p);
	self.showAt(p.x, p.y);
};

Zapatec.Calendar.prototype.setDateFormat = function (str) {
	this.dateFormat = str;
};

Zapatec.Calendar.prototype.setTtDateFormat = function (str) {
	this.ttDateFormat = str;
};

Zapatec.Calendar.prototype.parseDate = function (str, fmt) {
	if (!str)
		return this.setDate(this.date);
	if (!fmt)
		fmt = this.dateFormat;
	var date = Date.parseDate(str, fmt);
	return this.setDate(date);
};

Zapatec.Calendar.prototype.hideShowCovered = function () {
	if (!Zapatec.is_ie5)
		return;
	var self = this;
	function getVisib(obj){
		var value = obj.style.visibility;
		if (!value) {
			if (window.document.defaultView && typeof (window.document.defaultView.getComputedStyle) == "function") { // Gecko, W3C
				if (!Zapatec.is_khtml)
					value = window.document.defaultView.
						getComputedStyle(obj, "").getPropertyValue("visibility");
				else
					value = '';
			} else if (obj.currentStyle) {
				value = obj.currentStyle.visibility;
			} else
				value = '';
		}
		return value;
	};
	var tags = ["applet", "iframe", "select"];
	var el = self.element;
	var p = Zapatec.Utils.getAbsolutePos(el);
	var EX1 = p.x;
	var EX2 = el.offsetWidth + EX1;
	var EY1 = p.y;
	var EY2 = el.offsetHeight + EY1;
	for (var k = tags.length; k > 0; ) {
		var ar = window.document.getElementsByTagName(tags[--k]);
		var cc = null;
		for (var i = ar.length; i > 0;) {
			cc = ar[--i];
			p = Zapatec.Utils.getAbsolutePos(cc);
			var CX1 = p.x;
			var CX2 = cc.offsetWidth + CX1;
			var CY1 = p.y;
			var CY2 = cc.offsetHeight + CY1;
			if (self.hidden || (CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) {
				if (!cc.__msh_save_visibility) {
					cc.__msh_save_visibility = getVisib(cc);
				}
				cc.style.visibility = cc.__msh_save_visibility;
			} else {
				if (!cc.__msh_save_visibility) {
					cc.__msh_save_visibility = getVisib(cc);
				}
				cc.style.visibility = "hidden";
			}
		}
	}
};

Zapatec.Calendar.prototype._displayWeekdays = function () {
	var fdow = this.firstDayOfWeek;
	var cell = this.firstdayname;
	var weekend = Zapatec.Calendar.i18n("WEEKEND");
	for (k = 1; (k <= this.monthsInRow) && (cell); ++k) {
		for (var i = 0; i < 7; ++i) {
			cell.className = " day name";
			if ((!this.weekNumbers) && (i == 0) && (k != 1)) {
				Zapatec.Utils.addClass(cell, "month-left-border");
			}
			if ((i == 6) && (k != this.monthsInRow)) {
				Zapatec.Utils.addClass(cell, "month-right-border");
			}
			var realday = (i + fdow) % 7;
			if ((!this.disableFdowClick) && ((this.params && this.params.fdowClick) || i)) {
				if (Zapatec.Calendar.i18n("DAY_FIRST") != null) {
					cell.ttip = Zapatec.Calendar.i18n("DAY_FIRST").replace("%s", Zapatec.Calendar.i18n(realday, "dn"));
				}
				cell.navtype = 100;
				cell.calendar = this;
				cell.fdow = realday;
				Zapatec.Calendar._add_evs(cell);
			}
			if ((weekend != null) && (weekend.indexOf(realday.toString()) != -1)) {
							Zapatec.Utils.addClass(cell, "weekend");
			}
			cell.innerHTML = Zapatec.Calendar.i18n((i + fdow) % 7, "sdn");
			cell = cell.nextSibling;
		}
		if (this.weekNumbers && cell) {
			cell = cell.nextSibling;
		}
	}
};

Zapatec.Utils.compareDates = function(date1, date2)
{
	if (Zapatec.Calendar.prefs.sortOrder == "asc")
		return date1 - date2;
	else 
		return date2 - date1;
}

Zapatec.Calendar.prototype._hideCombos = function () {
	this.monthsCombo.style.display = "none";
	this.yearsCombo.style.display = "none";
	this.histCombo.style.display = "none";
	this.updateWCH();
};

Zapatec.Calendar.prototype._dragStart = function (ev) {
	ev || (ev = window.event);
	if (this.dragging) {
		return;
	}
	this.dragging = true;
	var posX = ev.clientX + window.document.body.scrollLeft;
	var posY = ev.clientY + window.document.body.scrollTop;
	var st = this.element.style;
	this.xOffs = posX - parseInt(st.left);
	this.yOffs = posY - parseInt(st.top);
	Zapatec.Utils.addEvent(window.document, "mousemove", Zapatec.Calendar.calDragIt);
	Zapatec.Utils.addEvent(window.document, "mouseover", Zapatec.Calendar.calDragIt);
	Zapatec.Utils.addEvent(window.document, "mouseup", Zapatec.Calendar.calDragEnd);
};

Date._MD = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
Date.SECOND = 1000;
Date.MINUTE = 60 * Date.SECOND;
Date.HOUR   = 60 * Date.MINUTE;
Date.DAY    = 24 * Date.HOUR;
Date.WEEK   =  7 * Date.DAY;

Date.prototype.getMonthDays = function(month) {
	var year = this.getFullYear();
	if (typeof month == "undefined") {
		month = this.getMonth();
	}
	if (((0 == (year%4)) && ( (0 != (year%100)) || (0 == (year%400)))) && month == 1) {
		return 29;
	} else {
		return Date._MD[month];
	}
};

Date.prototype.getDayOfYear = function() {
	var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
	var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0);
	var time = now - then;
	return Math.floor(time / Date.DAY);
};

Date.prototype.getWeekNumber = function() {
	var d = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
	var DoW = d.getDay();
	d.setDate(d.getDate() - (DoW + 6) % 7 + 3);
	var ms = d.valueOf();
	d.setMonth(0);
	d.setDate(4);
	return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1;
};

Date.prototype.equalsTo = function(date) {
	return ((this.getFullYear() == date.getFullYear()) &&
		(this.getMonth() == date.getMonth()) &&
		(this.getDate() == date.getDate()) &&
		(this.getHours() == date.getHours()) &&
		(this.getMinutes() == date.getMinutes()));
};

Date.prototype.dateEqualsTo = function(date) {
	return ((this.getFullYear() == date.getFullYear()) &&
		(this.getMonth() == date.getMonth()) &&
		(this.getDate() == date.getDate()));
};

Date.prototype.setDateOnly = function(date) {
	var tmp = new Date(date);
	this.setDate(1);
	this.setFullYear(tmp.getFullYear());
	this.setMonth(tmp.getMonth());
	this.setDate(tmp.getDate());
};

Date.prototype.print = function (str) {
	var m = this.getMonth();
	var d = this.getDate();
	var y = this.getFullYear();
	var wn = this.getWeekNumber();
	var w = this.getDay();
	var s = {};
	var hr = this.getHours();
	var pm = (hr >= 12);
	var ir = (pm) ? (hr - 12) : hr;
	var dy = this.getDayOfYear();
	if (ir == 0)
		ir = 12;
	var min = this.getMinutes();
	var sec = this.getSeconds();
	s["%a"] = Zapatec.Calendar.i18n(w, "sdn");
	s["%A"] = Zapatec.Calendar.i18n(w, "dn");
	s["%b"] = Zapatec.Calendar.i18n(m, "smn");
	s["%B"] = Zapatec.Calendar.i18n(m, "mn");
	s["%C"] = 1 + Math.floor(y / 100);
	s["%d"] = (d < 10) ? ("0" + d) : d;
	s["%e"] = d;
	s["%H"] = (hr < 10) ? ("0" + hr) : hr;
	s["%I"] = (ir < 10) ? ("0" + ir) : ir;
	s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy;
	s["%k"] = hr ? hr :  "0";
	s["%l"] = ir;
	s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m);
	s["%M"] = (min < 10) ? ("0" + min) : min;
	s["%n"] = "\n";
	s["%p"] = pm ? "PM" : "AM";
	s["%P"] = pm ? "pm" : "am";
	s["%s"] = Math.floor(this.getTime() / 1000);
	s["%S"] = (sec < 10) ? ("0" + sec) : sec;
	s["%t"] = "\t";
	s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn;
  s["%u"] = (w == 0) ? 7 : w;
	s["%w"] = w ? w : "0";
	s["%y"] = ('' + y).substr(2, 2);
	s["%Y"] = y;
	s["%%"] = "%";
	var re = /%./g;
	var a = str.match(re);
	for (var i = 0; i < a.length; i++) {
		var tmp = s[a[i]];
		if (tmp) {
			re = new RegExp(a[i], 'g');
			str = str.replace(re, tmp);
		}
	}
	return str;
};

Date.parseDate = function (str, fmt) {
	if (!str)
		return new Date();
	var y = 0;
	var m = -1;
	var d = 0;
	var a = str.split(/\W+/);
	var b = fmt.match(/%./g);
	var i = 0, j = 0;
	var hr = 0;
	var min = 0;
	var sec = 0;
	for (i = 0; i < a.length; ++i) {
		if (!a[i])
			continue;
		switch (b[i]) {
		    case "%d":
		    case "%e":
			d = parseInt(a[i], 10);
			break;
		    case "%m":
			m = parseInt(a[i], 10) - 1;
			break;
		    case "%Y":
		    case "%y":
			y = parseInt(a[i], 10);
			(y < 100) && (y += (y > 29) ? 1900 : 2000);
			break;
		    case "%b":
			for (j = 0; j < 12; ++j)
				if (Zapatec.Calendar.i18n(j, "smn").toLowerCase() == a[i].toLowerCase()) {
					m = j;
					break;
				}
			break;
		    case "%B":
			for (j = 0; j < 12; ++j)
				if (Zapatec.Calendar.i18n(j, "mn").toLowerCase() == a[i].toLowerCase()) {
					m = j;
					break;
				}
			break;
		    case "%H":
		    case "%I":
		    case "%k":
		    case "%l":
			hr = parseInt(a[i], 10);
			break;
		    case "%P":
		    case "%p":
			if (/pm/i.test(a[i]) && hr < 12)
				hr += 12;
			if (/am/i.test(a[i]) && hr == 12)
				hr = 0;
			break;
		    case "%M":
			min = parseInt(a[i], 10);
			break;
		    case "%S":
			sec = parseInt(a[i], 10);
			break;
		}
	}
	var validDate = !isNaN(y) && !isNaN(m) && !isNaN(d) && !isNaN(hr) && !isNaN(min) && !isNaN(sec);
	if (!validDate) {return null;}
	if (y != 0 && m != -1 && d != 0)
		return new Date(y, m, d, hr, min, sec);
	y = 0; m = -1; d = 0;
	for (i = 0; i < a.length; ++i) {
		if (a[i].search(/[a-zA-Z]+/) != -1) {
			var t = -1;
			for (j = 0; j < 12; ++j)
				if (Zapatec.Calendar.i18n(j, "mn").substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) {
					t = j;
					break;
				}
			if (t != -1) {
				if (m != -1)
					d = m+1;
				m = t;
			}
		} else if (parseInt(a[i], 10) <= 12 && m == -1) {
			m = a[i]-1;
		} else if (parseInt(a[i], 10) > 31 && y == 0) {
			y = parseInt(a[i], 10);
			(y < 100) && (y += (y > 29) ? 1900 : 2000);
		} else if (d == 0) {
			d = a[i];
		}
	}
	if (y == 0) {
		var today = new Date();
		y = today.getFullYear();
	}
	if (m != -1 && d != 0)
		return new Date(y, m, d, hr, min, sec);
	return null;
};

Date.prototype.__msh_oldSetFullYear = Date.prototype.setFullYear;

Date.prototype.setFullYear = function(y) {
	var d = new Date(this);
	d.__msh_oldSetFullYear(y);
	if (d.getMonth() != this.getMonth())
		this.setDate(28);
	this.__msh_oldSetFullYear(y);
};

Date.prototype.compareDatesOnly = function (date1,date2) { 
	var year1 = date1.getYear();
	var year2 = date2.getYear(); 
	var month1 = date1.getMonth(); 
	var month2 = date2.getMonth(); 
	var day1 = date1.getDate(); 
	var day2 = date2.getDate(); 
	if (year1 > year2) { return -1;	} 
	if (year2 > year1) { return 1; }
	if (month1 > month2) { return -1; } 
	if (month2 > month1) { return 1; }
	if (day1 > day2) { return -1; } 
	if (day2 > day1) { return 1; }
	return 0; 
}

Zapatec.Setup = function () {};
Zapatec.Setup.test = true;

Zapatec.Calendar.setup = function (params) {
	paramsList = ["id"];
	function param_default(pname, def) { 
		if (typeof params[pname] == "undefined") { 
			params[pname] = def; 
		} 
		paramsList.push(pname);
	};
	params.id = Zapatec.Utils.generateID("calendar");
	param_default("inputField",     null);
	param_default("displayArea",    null);
	param_default("button",         null);
	param_default("eventName",      "click");
	param_default("closeEventName", null);
	param_default("ifFormat",       "%Y/%m/%d");
	param_default("daFormat",       "%Y/%m/%d");
	param_default("singleClick",    true);
	param_default("disableFunc",    null);
	param_default("dateStatusFunc", params["disableFunc"]);	// takes precedence if both are defined
	param_default("dateText",       null);
	param_default("firstDay",       null);
	param_default("align",          "Br");
	param_default("range",          [1900, 2999]);
	param_default("weekNumbers",    true);
	param_default("flat",           null);
	param_default("flatCallback",   null);
	param_default("onSelect",       null);
	param_default("onClose",        null);
	param_default("onUpdate",       null);
	param_default("date",           null);
	param_default("showsTime",      false);
	param_default("sortOrder",      "asc");
	param_default("timeFormat",     "24");
	param_default("timeInterval",   null);
	param_default("electric",       true);
	param_default("step",           2);
	param_default("position",       null);
	param_default("cache",          false);
	param_default("showOthers",     false);
	param_default("multiple",       null);
	param_default("saveDate",       null);
	param_default("fdowClick",      false);
	param_default("titleHtml",      null);
	param_default("noHelp",         false);
	param_default("disableFdowChange", false);
	if (params.weekNumbers) {
		params.disableFdowChange = true;
	}
	param_default("disableDrag", false);
	param_default("numberMonths",   1);
	if ((params.numberMonths > 12) || (params.numberMonths < 1)) {
		params.numberMonths = 1;
	}
	if (params.numberMonths > 1) {
		params.showOthers = false;
	}
	params.numberMonths = parseInt(params.numberMonths, 10);
	param_default("controlMonth",   1);
	if ((params.controlMonth > params.numberMonths) || (params.controlMonth < 1)) {
		params.controlMonth = 1;
	}
	params.controlMonth = parseInt(params.controlMonth, 10);
	param_default("vertical",       false);
	if (params.monthsInRow > params.numberMonths) {
		params.monthsInRow = params.numberMonths;
	}
	param_default("monthsInRow",    params.numberMonths);
	params.monthsInRow = parseInt(params.monthsInRow, 10);
	param_default("multiple",       false);
	if (params.multiple) {
		params.singleClick = false;
	}
	var tmp = ["inputField", "displayArea", "button"];
	for (var i in tmp) {
		if (typeof params[tmp[i]] == "string") {
		    if (document.getElementById(params[tmp[i]]) != null) {
		        params[tmp[i]] = document.getElementById(params[tmp[i]]);
		    } else {
		        params[tmp[i]] = document.getElementsByName(params[tmp[i]])[0];
		    }
		}
	}
	if (!(params.flat || params.multiple || params.inputField || params.displayArea || params.button)) {
		alert("Calendar.setup '" + params.id + "':\n  Nothing to setup (no fields found).  Please check your code");
		return false;
	}
	if (((params.timeInterval) && ((params.timeInterval !== Math.floor(params.timeInterval)) || ((60 % params.timeInterval !== 0) && (params.timeInterval % 60 !== 0)))) || (params.timeInterval > 360)) {
		alert("'" + params.id + "': timeInterval option can only have the following number of minutes:\n1, 2, 3, 4, 5, 6, 10, 15, 30,  60, 120, 180, 240, 300, 360 ");
		params.timeInterval = null;
	}
	if (params.date && !Date.parse(params.date)) {
		alert("'" + params.id + "' Start Date Invalid: " + params.date + ".\nSee date option.\nDefaulting to today.");
		params.date = null;
	}
	if (params.saveDate) {
		param_default("cookiePrefix", window.location.href + "--" + params.button.id);
		var cookieName = params.cookiePrefix;
		var newdate = Zapatec.Utils.getCookie(cookieName);
		if (newdate != null) {
			document.getElementById(params.inputField.id).value = newdate;
		}
	}
	for(var ii in params) {
		if (Zapatec.Utils.arrIndexOf(paramsList, ii) == -1) {
			alert("Wrong config option: " + ii);
		}
	}
	function onSelect(cal) {
		var p = cal.params;
		var update = (cal.dateClicked || p.electric);
		if (update && p.flat) {
			if (typeof p.flatCallback == "function")
			{
			   if (!p.multiple)
				p.flatCallback(cal);
			} else
				alert("'" + cal.id + "': No flatCallback given -- doing nothing.");
			return false;
		}
		if (update && p.inputField) {
			p.inputField.value = cal.currentDate.print(p.ifFormat);
			if (typeof p.inputField.onchange == "function")
				p.inputField.onchange();
		}
		if (update && p.displayArea)
			p.displayArea.innerHTML = cal.currentDate.print(p.daFormat);
		if (update && p.singleClick && cal.dateClicked)
			cal.callCloseHandler();
		if (update && typeof p.onUpdate == "function")
			p.onUpdate(cal);
		if (p.saveDate) {
			var cookieName = p.cookiePrefix;
			Zapatec.Utils.writeCookie(cookieName, p.inputField.value, null, '/', p.saveDate);
		} 
	};
	if (params.flat != null) {
		if (typeof params.flat == "string")
			params.flat = document.getElementById(params.flat);
		if (!params.flat) {
			alert("Calendar.setup '" + params.id + "':\n  Flat specified but can't find parent.");
			return false;
		}
		var cal = new Zapatec.Calendar(params.firstDay, params.date, params.onSelect || onSelect);
		cal.id = params.id;
		cal.disableFdowClick = params.disableFdowChange;
		cal.showsOtherMonths = params.showOthers;
		cal.showsTime = params.showsTime;
		cal.time24 = (params.timeFormat == "24");
		cal.timeInterval = params.timeInterval;
		cal.params = params;
		cal.weekNumbers = params.weekNumbers;
		cal.sortOrder = params.sortOrder.toLowerCase();
		cal.setRange(params.range[0], params.range[1]);
		cal.setDateStatusHandler(params.dateStatusFunc);
		cal.getDateText = params.dateText;
		cal.numberMonths = params.numberMonths;
		cal.controlMonth = params.controlMonth;
		cal.vertical = params.vertical;
		cal.yearStep = params.step;
		cal.monthsInRow = params.monthsInRow;
		cal.helpButton = !params.noHelp;
		if (params.ifFormat) {
			cal.setDateFormat(params.ifFormat);
		}
		if (params.inputField && params.inputField.type == "text" && typeof params.inputField.value == "string") {
			cal.parseDate(params.inputField.value);
		}
		if (params.multiple) {
		   cal.setMultipleDates(params.multiple);
		}
		cal.create(params.flat);
		cal.show();
		return cal;
	}
	var triggerEl = params.button || params.displayArea || params.inputField;
	triggerEl["on" + params.eventName] = function() {
		var dateEl = params.inputField || params.displayArea;
		if (triggerEl.blur) {triggerEl.blur();}
		var dateFmt = params.inputField ? params.ifFormat : params.daFormat;
		var mustCreate = false;
		var cal = window.calendar;
		if (!(cal && params.cache)) {
			window.calendar = cal = new Zapatec.Calendar(params.firstDay,
							     params.date,
							     params.onSelect || onSelect,
							     params.onClose || function(cal) {
								     if (params.cache)
									     cal.hide();
								     else
									     cal.destroy();
							     });
			cal.id = params.id;
			cal.disableFdowClick = params.disableFdowChange;
			cal.showsTime = params.showsTime;
			cal.time24 = (params.timeFormat == "24");
			cal.timeInterval = params.timeInterval;
			cal.weekNumbers = params.weekNumbers;
			cal.numberMonths = params.numberMonths;
			cal.controlMonth = params.controlMonth;
			cal.vertical = params.vertical;
			cal.monthsInRow = params.monthsInRow;			
			cal.historyDateFormat = params.ifFormat || params.daFormat;
			cal.helpButton = !params.noHelp;
			cal.disableDrag = params.disableDrag;
			mustCreate = true;
		} else {
			if (params.date)
				cal.setDate(params.date);
			cal.hide();
		}
		if (params.multiple) {
		   cal.setMultipleDates(params.multiple);
		}
		cal.showsOtherMonths = params.showOthers;
		cal.yearStep = params.step;
		cal.setRange(params.range[0], params.range[1]);
		cal.params = params;
		cal.setDateStatusHandler(params.dateStatusFunc);
		cal.getDateText = params.dateText;
		cal.setDateFormat(dateFmt);
		if (mustCreate)
			cal.create();
		if (dateEl) {
			var dateValue;
			if (dateEl.value) {
				dateValue = dateEl.value;
			} else {
				dateValue = dateEl.innerHTML;
			}
			if (dateValue != "") {
				var parsedDate = Date.parseDate(dateEl.value || dateEl.innerHTML, dateFmt);
				if (parsedDate != null) {
					cal.setDate(parsedDate);
				}
			}
		}
		if (!params.position)
			cal.showAtElement(params.button || params.displayArea || params.inputField, params.align);
		else
			cal.showAt(params.position[0], params.position[1]);
		return false;
	};
	if (params.closeEventName) {
		triggerEl["on" + params.closeEventName] = function() {
			if (window.calendar)
				window.calendar.callCloseHandler();
		};
	}
	return cal;
};